/* ==========================================================================
   Overview — one screen, no scrolling at 1440×900 or 1280×800.
   What waits for a person first (the greeting, then the review band in the attention treatment),
   then the agent systems, then the sites and their power now.
   Bento: 12 columns, three rows. Correspondence 4 cols · Prioritization 3 cols · Grid-first 5 cols over two rows;
   the Grid researcher as one line under Correspondence and Prioritization; then Sites 7 cols · Power 5 cols.
   Every tile says what its figures cover right after its title (.ov-scope); Prioritization and Grid-first then carry
   their agent's mark (.ov-mark).
   ========================================================================== */
.view-overview .page { height: 100%; min-height: 660px; display: flex; flex-direction: column; gap: var(--gap); padding-top: 8px; padding-bottom: 24px; }

/* ---------- What waits for you ---------- */
.ov-hello { flex: none; display: flex; align-items: baseline; gap: 16px; min-width: 0; padding: 0 2px; }
.ov-date { white-space: nowrap; }

/* The review queue as a band: the title and its red count on the left (how many more wait under it), then up to
   three requests side by side, each in the attention treatment. Inside a request: who asked | the decision (two
   lines at most) | 'To inbox'; under the decision, who asked, and at its end how long it has waited. */
.ov-review { position: relative; flex: none; animation: rise var(--dur-3) var(--ease) both; }
.ov-review .queue { flex-direction: row; align-items: stretch; }
.ov-review .queue-head { flex: none; align-self: flex-start; min-height: 0; padding: 12px 24px 12px 14px; }
.ov-review .queue-list { flex: 1 1 auto; min-width: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.ov-review .queue-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "who title go" "who meta meta"; column-gap: 12px; row-gap: 4px; padding: 12px; }
.ov-review .queue-row-main { display: contents; }
.ov-review .queue-who { grid-area: who; }
.ov-review .queue-row-main > b { grid-area: title; }
.ov-review .queue-go { grid-area: go; align-self: start; justify-self: end; margin: 0; }
/* The wait shares the meta's cell, at its bottom right; the meta keeps clear of it and sits on the same last line. */
.ov-review .queue-row-meta { grid-area: meta; align-self: end; padding-right: 56px; }
.ov-review .queue-row-age { grid-area: meta; align-self: end; justify-self: end; }
.ov-review .queue-none { padding: 12px 14px; }
.ov-review-more { position: absolute; left: 22px; bottom: 18px; }

/* ---------- Bento ---------- */
.ov-bento {
  --ov-bottom: 184px;
  flex: 1 1 auto; min-height: 0; display: grid; gap: var(--gap);
  grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr) auto var(--ov-bottom);
}
.ov-corr     { grid-area: 1 / 1 / 2 / 5; }
.ov-prio     { grid-area: 1 / 5 / 2 / 8; }
.ov-research { grid-area: 2 / 1 / 3 / 8; }
.ov-grid     { grid-area: 1 / 8 / 3 / 13; }
.ov-sites    { grid-area: 3 / 1 / 4 / 8; }
.ov-power    { grid-area: 3 / 8 / 4 / 13; }

.ov-tile { overflow: hidden; animation: rise var(--dur-3) var(--ease) both; }
.ov-tile .tile-actions { gap: 4px; }
.ov-tile .tile-foot { gap: 16px; padding-top: 12px; }
.ov-tile .tile-foot .live { flex: 1 1 auto; }
/* What the tile's figures cover: which sites, since when. Right after the title, never under it, never cut. */
.ov-scope { flex: none; font-size: var(--fs-meta); line-height: 1.4; white-space: nowrap; }
.ov-none { font-size: var(--fs-body); }
.ov-foot-text { min-width: 0; font-size: var(--fs-meta); line-height: 1.4; }

/* ---------- An agent at work, as its own mark: after the tile's title (and its scope), away from the controls ----------
   Still and faded to --stroke while the agent waits or it or its system is off, like an idle agent's glyph; ink and
   moving only while it works (.is-working, on the mark and its tile). Both keep the yin-yang's working pace (a round
   every --turn / 2) on one clock (--ov-phase, set by the view), so a repainted tile never restarts its mark. Under
   prefers-reduced-motion a working mark holds a still working pose in ink instead: one bar out of the ranks, the
   scope's hand at rest with its sweep behind it. */
.ov-mark { flex: none; display: block; margin-left: 4px; color: var(--stroke); cursor: default; }
.ov-mark.is-working { color: var(--ink); }

/* The prioritizer: its glyph's bars, longest first, a ranked list. While it works it re-ranks twice a round: the third
   bar draws back out of its place, the bars above it step down a place, and it draws in again at the top; then the
   fourth does the same into second place. Each bar's places in the round, as top and length (0, 1, 2: before, between
   and after the two moves); the round ends on the picture it began with, so it loops without a seam. */
.ov-rank { position: relative; width: 28px; height: 24px; }
.ov-rank > i { position: absolute; left: 2px; top: 0; width: var(--l0); height: 2px; border-radius: 1px; background: currentColor; transform: translateY(var(--y0)); }
.ov-rank > .b1 { --y0: 3.5px; --l0: 22px; --y1: 8.5px; --l1: 16px; --y2: 13.5px; --l2: 11px; }
.ov-rank > .b2 { --y0: 8.5px; --l0: 16px; --y1: 13.5px; --l1: 11px; --y2: 18.5px; --l2: 6px; }
.ov-rank > .b3 { --y0: 13.5px; --l0: 11px; --y1: 3.5px; --l1: 22px; }
.ov-rank > .b4 { --y0: 18.5px; --l0: 6px; --y2: 8.5px; --l2: 16px; }
.ov-rank.is-working > .b3 { transform: translate(5px, var(--y0)); }   /* the still working pose: out of its place */
.ov-rank.is-working > i { animation: ov-rank-step calc(var(--turn) / 2) var(--ease-io) var(--ov-phase, 0s) infinite; }
.ov-rank.is-working > .b3 { animation-name: ov-rank-up-a; }
.ov-rank.is-working > .b4 { animation-name: ov-rank-up-b; }
@keyframes ov-rank-step {
  0%, 16% { width: var(--l0); transform: translateY(var(--y0)); }
  28%, 66% { width: var(--l1); transform: translateY(var(--y1)); }
  78%, 100% { width: var(--l2); transform: translateY(var(--y2)); }
}
@keyframes ov-rank-up-a {
  0%, 8% { width: var(--l0); transform: translateY(var(--y0)); }
  16% { width: 0; transform: translateY(var(--y0)); }
  28% { width: 0; transform: translateY(var(--y1)); }
  38%, 100% { width: var(--l1); transform: translateY(var(--y1)); }
}
@keyframes ov-rank-up-b {
  0%, 58% { width: var(--l0); transform: translateY(var(--y0)); }
  66% { width: 0; transform: translateY(var(--y0)); }
  78% { width: 0; transform: translateY(var(--y2)); }
  88%, 100% { width: var(--l2); transform: translateY(var(--y2)); }
}

/* The scout: its scope round a substation; while it works a hand sweeps the ground around it, clockwise. */
.ov-radar { width: 28px; height: 28px; }
.ov-radar svg { display: block; width: 100%; height: 100%; overflow: visible; }
.ov-radar-ring, .ov-radar-ticks, .ov-radar-hand { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.ov-radar-core { fill: currentColor; }
.ov-radar-wedge { fill: var(--fill-2); }
.ov-radar-sweep { display: none; transform-origin: 14px 14px; transform: rotate(45deg); }
.ov-radar.is-working .ov-radar-sweep { display: inline; animation: ov-sweep calc(var(--turn) / 2) linear var(--ov-phase, 0s) infinite; }
@keyframes ov-sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .ov-rank.is-working > i, .ov-rank.is-working > .b3, .ov-rank.is-working > .b4, .ov-radar.is-working .ov-radar-sweep { animation: none; }
}

/* ---------- Correspondence: Wren and Vera fill the middle of the outbox hour ---------- */
.ov-corr-body { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; gap: 24px; }
/* The face takes the body's height up to --dial, so it never runs into the tile's head or foot. */
.ov-dial { --dial: 192px; position: relative; flex: none; height: min(var(--dial), 100%); aspect-ratio: 1; }
.ov-dial-svg { width: 100%; height: 100%; overflow: visible; }
.ov-dial-ring { fill: none; stroke: var(--fill-2); stroke-width: 3; }
.ov-dial-ticks line { stroke: var(--stroke-faint); stroke-width: 1.25; stroke-linecap: round; }
.ov-dial-ticks line.q { stroke: var(--stroke); }
.ov-dial-now { fill: var(--ink); }
.ov-dial-dot { fill: var(--ink); stroke: var(--surface); stroke-width: 2.5; cursor: pointer; }
.ov-dial-dot:hover { fill: var(--ink-hover); }
.ov-dial-center { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
/* The yin-yang fills the ring: 130 of the face's 168 units, just inside the dots that ride the ring.
   At this size its rim is drawn fine, so the white half keeps a hairline edge rather than a band. */
.ov-dial-center .busy { width: calc(100% * 130 / 168); height: calc(100% * 130 / 168); border-radius: 50%; pointer-events: auto; }
.ov-dial .busy-mark { width: 100%; height: 100%; }
.ov-dial .busy-mark .bm-rim { stroke-width: .3; }
.ov-corr.is-off .ov-dial-ring { stroke: var(--fill); }

.ov-out { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ov-out-row { display: flex; align-items: center; gap: 12px; min-width: 0; margin: 0 -10px; padding: 8px 10px; border-radius: var(--r-2); text-decoration: none; transition: background var(--dur-1) var(--ease); }
.ov-out-row:hover { background: var(--hover); }
.ov-out-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ov-out-name { font-weight: 500; }   /* names never truncate */
.ov-out-meta { display: flex; align-items: center; min-width: 0; font-size: var(--fs-meta); line-height: 1.4; white-space: nowrap; }
.ov-out-more { align-self: flex-start; margin-top: 6px; }

/* ---------- Prioritization: the order the grid researcher takes, each site with the facts its place rests on ---------- */
.ov-sub { align-self: flex-start; margin: 6px 0 6px; font-size: var(--fs-body); font-weight: 500; line-height: 1.45; }
/* Rows that do not fit wrap into a second column outside the box, which is clipped (and the view hides them, so the
   keyboard never lands on one): a row shows whole or not at all. The list bleeds by the rows' padding, so their
   hover sits on the tile's edges. */
.ov-nexts { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; flex-wrap: wrap; align-content: flex-start; gap: 4px 24px; margin: 0 -10px; overflow: clip; overflow-clip-margin: 4px; }
.ov-next { display: flex; align-items: baseline; gap: 12px; width: 100%; min-width: 0; padding: 6px 10px; border: 0; border-radius: var(--r-2); background: none; color: inherit; text-align: left; transition: background var(--dur-1) var(--ease); }
.ov-next:hover { background: var(--hover); }
.ov-next-n { flex: none; width: 10px; font-weight: 500; font-variant-numeric: tabular-nums; }
.ov-next-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ov-next-name { min-width: 0; }
.ov-next-name b { font-weight: 500; }
.ov-next-live { display: inline-flex; align-items: center; height: 1lh; margin-left: 8px; vertical-align: top; }
.ov-next-basis { font-size: var(--fs-meta); line-height: 1.4; }
.ov-next-basis .src { vertical-align: -1px; }

/* ---------- Grid researcher: one line, the sites it researches now, then its sessions and its switch ---------- */
.ov-research { justify-content: center; }
.ov-research .tile-head { gap: 16px; }
.ov-res { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 4px; margin: -4px 0; }
/* Its glyph: breathing while it works; idle, it fades */
.ov-res-me { flex: none; display: flex; margin-right: 2px; }
.ov-res-me.is-idle .av { --av-fg: var(--stroke); }
/* A site it researches now: the place opens the site's record */
.ov-res-cell { flex: 0 1 auto; display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 36px; padding: 4px 8px; border: 0; border-radius: var(--r-2); background: none; text-align: left; transition: background var(--dur-1) var(--ease); }
.ov-res-cell:hover { background: var(--hover); }
/* Off: the switch says it, and one quiet line what it means beside the work still under way */
.ov-res-off { flex: none; padding-left: 6px; font-size: var(--fs-meta); line-height: 1.4; white-space: nowrap; }
.ov-res-place, .ov-res-said { min-width: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--fs-meta); line-height: 1.4; }
.ov-res-said { padding-left: 6px; }
.ov-stopped { flex: none; width: 8px; height: 8px; margin: 0 -2px; border-radius: 2px; background: var(--ink); }

/* ---------- Grid-first: the areas people marked, how far the scout is in each, the plots that wait ---------- */
.ov-areas { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; flex-wrap: wrap; align-content: flex-start; gap: 2px 24px; margin: 10px -12px 0; overflow: clip; overflow-clip-margin: 4px; }
.ov-area { display: flex; flex-direction: column; gap: 6px; width: 100%; min-width: 0; padding: 9px 12px; border-radius: var(--r-3); color: inherit; text-decoration: none; transition: background var(--dur-1) var(--ease); }
.ov-area:hover { background: var(--hover); }
.ov-area-top { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 12px; min-width: 0; }
.ov-area-name { min-width: 0; }
.ov-area-name b { font-weight: 500; }
.ov-area-status { flex: none; display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-meta); line-height: 1.4; white-space: nowrap; }
.ov-area-review { margin-left: auto; flex: none; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ov-area-work { display: flex; align-items: center; gap: 10px; min-width: 0; font-size: var(--fs-meta); line-height: 1.4; }
.ov-area-work .progress { flex: 0 0 64px; }
.ov-area-n { min-width: 0; font-variant-numeric: tabular-nums; }
/* What the scout says, on the area it searches: its own words, two lines at most. */
.ov-area-says { min-width: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--fs-meta); line-height: 1.4; }
/* The one action sits at the right; the scout's words, when they belong to no area here, at the left. */
.ov-grid .tile-foot { align-items: flex-end; }
.ov-grid .tile-foot > :last-child { margin-left: auto; }
.ov-plots-btn { flex: none; gap: 8px; }
.ov-plots-btn .count { min-width: 22px; }
.ov-plots-btn .ic { width: 14px; height: 14px; margin-right: -2px; }

/* ---------- Sites: the pipeline now, one count per stage in the order a site moves; Set aside stands apart ---------- */
/* Its head: New site, then the way to the board */
.ov-sites .tile-actions { gap: 16px; }
.ov-pipe { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; gap: 20px; margin: 0 -12px; }
.ov-stages { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; justify-content: space-between; }
.ov-stage { position: relative; flex: none; display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 10px 12px 12px; border-radius: var(--r-3); color: inherit; text-decoration: none; transition: background var(--dur-1) var(--ease); }
.ov-stage:not(.attn):hover { background: var(--hover); }
.ov-stage-n { font-size: var(--fs-figure); font-weight: 300; line-height: 1.1; font-variant-numeric: tabular-nums; }
.ov-stage-name { font-weight: 500; white-space: nowrap; }
.ov-flow { flex: none; display: grid; place-items: center; color: var(--stroke); }
.ov-flow .ic { width: 16px; height: 16px; }
.ov-stage.s-aside { flex: none; }
.ov-stage.s-aside::before { content: ""; position: absolute; left: -10px; top: 12px; bottom: 12px; width: 1px; background: var(--line); }

/* ---------- Power: the total at the active sites, and how sure we are of each part of it ---------- */
.ov-power-body { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; gap: 28px; }
.ov-donut { --donut: 108px; position: relative; flex: none; width: var(--donut); height: var(--donut); }
.ov-donut-svg { width: 100%; height: 100%; overflow: visible; }
.ov-arc { fill: none; }
.ov-arc.k-writing { stroke: var(--ink); }
.ov-arc.k-stated { stroke: var(--stroke); }
.ov-arc.k-estimate { stroke: var(--stroke-faint); }
.ov-arc.k-disagree { fill: transparent; stroke: var(--stroke); stroke-linejoin: round; }   /* hollow: not settled */
.ov-arc.k-none { stroke: var(--fill-2); }
/* The middle lets the ring's segments take the pointer; only the total itself answers it. */
.ov-donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.ov-donut-n { display: inline-flex; align-items: baseline; pointer-events: auto; }
.ov-donut-l { margin-top: 2px; font-size: var(--fs-meta); line-height: 1.4; }
.ov-legend { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.ov-leg { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ov-leg .src { flex: 1 1 auto; min-width: 0; font-size: var(--fs-body); gap: 10px; }
.ov-leg .src-glyph { width: 14px; }
.ov-leg-n { flex: none; min-width: 52px; font-size: var(--fs-meta); line-height: 1.4; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ov-leg-v { flex: none; min-width: 84px; font-weight: 500; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------- Smaller screens (1280×800) ---------- */
@media (max-height: 860px) {
  .view-overview .page { padding-top: 4px; padding-bottom: 16px; min-height: 600px; }
  .ov-hello { gap: 14px; }
  .ov-bento { --ov-bottom: 168px; }
  .ov-tile { padding: 16px 20px; }
  .ov-dial { --dial: 164px; }
  .ov-corr-body { gap: 20px; }
  .ov-out-row { padding: 6px 10px; }
  .ov-sub { margin: 2px 0 2px; }
  .ov-nexts { row-gap: 0; }
  .ov-next { padding: 4px 10px; }
  .ov-areas { margin-top: 4px; row-gap: 0; }
  .ov-area { padding: 6px 12px; gap: 4px; }
  .ov-plots-btn { --h: 32px; }
  .ov-tile .tile-foot { padding-top: 8px; }
  .ov-donut { --donut: 100px; }
  .ov-power-body { gap: 24px; }
  .ov-legend { gap: 6px; }
}
