/* ================= THE CANONICAL OKR PAGE, IN THE SUITE'S CLOTHES =================

   okrs.html's workflow is unchanged; what changed is the surface it is
   drawn on — it now loads the suite's shell, like every other page. This
   file bridges the two: it builds the OKR context toolbar, and it teaches
   the classic OKR components the suite's control language.

   A stylesheet rather than a markup change, because most of what this
   page draws is shared code that also feeds the task app and the team
   board through the shared dialog — rewriting those class names would be
   editing files this page does not own, twice over. So the classic class
   names stay, scoped under `.alt-app` so this file reaches nothing
   outside this page, the same argument CSS/alt/alt-shared-dialogs.css
   makes for the Message Center.

   No token is redefined here — every value comes from a `--a-*` role
   token or a canonical one, so light mode comes free.

   The health states are not restyled here, only reshaped: they already
   take their colour from `--okr-*` in CSS/tokens.css, which points at the
   same roles the suite does. What the classic pill lacked was the
   suite's CHIP shape. */

/* ================= 1 · THE PAGE ================= */

/* The suite's page rhythm: the shell's own bands use --a-3/--a-4, and the
   board should sit on the same grid rather than at the classic 16/20. */
.alt-app main.okr-main{ padding:var(--a-3) var(--a-4) var(--a-6); }

/* ---------- AND THE BOARD HAS TO BE ABLE TO SCROLL ----------

   Neither the List nor the Kanban had a vertical scrollbar, so content
   below the fold was unreachable. The cause is the shell adoption, not
   the OKR code: `alt-shell.css` gives `.alt-app` `height:100dvh` and
   `overflow:hidden` at 1024 and up, so the document stops scrolling and
   some box inside has to take the job over — the classic page never had
   to nominate one.

   This is the suite's existing shape, not a new one: a column that may
   grow, `min-height:0` so it can be shorter than its content, and the
   region inside owns the overflow. `#okrApp` is the wrapper; `main.okr-
   main` is the region. Both views render into `#okrObjectives` inside
   that main, which is why one rule fixes List and Kanban together.

   Below 1024 the document scrolls again, so the scroller releases there
   — a `min-height:0; overflow:auto` child of a box no longer height-
   constrained scrolls at zero height otherwise. */
.alt-app #okrApp{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
@media (min-width:1024px){
  /* The scrollport gives up its top padding — the second half of the
     pinned-header defect: a sticky offset measures from the scroller's
     CONTENT box, so padding-top here pins the header below the
     scrollport's top, leaving a band the list slides past above it. The
     rhythm is not lost, it MOVES: §4 gives the header itself the same gap,
     inside an opaque background nothing can scroll through. */
  .alt-app main.okr-main{ flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; padding-top:0; }
  /* The pinned header has to re-anchor with it, since `position:sticky`
     measures `top` from its scroll root. Deliberately NOT declared here —
     it was once, and was dead code: a media query adds no specificity, so
     the later base rule in §4 always won. `top` is owned in exactly one
     place now; see §4 · PINNING. */
}

/* Headings in the suite's display face — the OKR surface draws several
   of its headings as spans and divs, and these are the ones that read as titles. */
.alt-app .okr-group-title,
.alt-app .okr-obj-title,
.alt-app .okr-detail-title,
.alt-app .okr-ctx-title{ font-family:var(--a-display); }

/* Numbers are figures, and figures line up. The suite reads them in JetBrains Mono. */
.alt-app .okr-stat-n,
.alt-app .okr-obj-pct,
.alt-app .okr-donut-num{ font-family:var(--a-mono); font-variant-numeric:tabular-nums; }

/* ================= 2 · THE OKR CONTEXT TOOLBAR =================

   One row that wraps, not a stack of bands. Three groups: what this board
   is, how it is shown, what acts on it. The middle group takes the free
   space so the two anchors keep their ends of the bar — the same rule
   the shell's own bar follows. */
.alt-app .okr-ctx{
  display:flex; align-items:center; gap:var(--a-3); flex-wrap:wrap;
  padding:var(--a-2) var(--a-3);
  background:var(--a-panel); border:1px solid var(--a-line); border-radius:var(--a-r);
  margin-bottom:var(--a-2);
}
.alt-app .okr-ctx-id{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:0 1 auto; }
.alt-app .okr-ctx-title{
  font-family:var(--a-display); font-size:17px; font-weight:700; letter-spacing:.01em;
  margin:0; color:var(--a-text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* The quarter and the count — the caption of the name it belongs to. */
.alt-app .okr-ctx-sub{ font-size:11px; color:var(--a-dim); white-space:nowrap; }

/* Which team — rendered only for an account with more than one.

   It is a captioned field, and was the only control in this row that was
   not: every other control lives inside `.okr-ctx-controls`, which sets
   `align-items:flex-end` so a two-row captioned field and a bare control
   land on one bottom edge. The team switch is a SIBLING of that group, so
   it was aligned by `.okr-ctx`'s own `align-items:center` instead and sat
   low, caption beside it rather than above it. Nothing was wrong with the
   select; it was in the wrong box.

   So it wears the same box as its siblings, `.a-field` from CSS/alt/alt-
   components.css — a column, an uppercase caption, its control under it —
   the same shape the team board's own Team selector uses. One control
   that picks a team, drawn one way, on both boards.

   `gap:5px` is `.a-field`'s caption gap and has to be, with no token for
   it: this field's control only lands on the same band as its neighbours
   because caption+gap+control here equals caption+gap+control there.
   `okr-team-switch-alignment.test.js` asserts the two agree rather than
   trusting this comment. The real fix is in the markup — giving the label
   `.a-field` directly in okrs.html would delete this box entirely — and
   is filed as a requirement to that file's owner.

   `align-self:flex-start`, not `center`: `.okr-ctx-controls` is the
   tallest item in the row, so its first flex line always begins at the
   row's content top, which is what keeps this field on that line when
   the controls wrap onto two.

   `margin-left:0` undoes a leak from CSS/okr.css's classic topbar rule,
   which gives this label a margin that follows a Team button this row
   does not have. Spacing here is `.okr-ctx`'s own gap.

   `align-items:flex-start` undoes a second leak from the same source:
   the classic rule's `align-items:center` meant something different
   there (an inline-flex row); turned into a column here, it shrink-wraps
   and centres the caption over the select instead of placing it above —
   genuinely centred, not merely short, which is what the owner's report *"Left align the team label as well"* had seen.
   It has to be `align-items`, not `text-align` — no text alignment can
   move a box its container has already shrunk and centred. `flex-start`
   rather than `stretch` so the select keeps sizing to its own content. */
.alt-app .okr-team-switch{
  display:flex; flex-direction:column; gap:5px; min-width:0;
  flex:0 0 auto; align-self:flex-start; align-items:flex-start; margin-left:0;
}
.alt-app .okr-team-switch .switcher-label{
  font-size:10px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:var(--a-dim);
}
/* No height here — it takes `--a-ctl` from `.alt-app select:not(.a-select)` below, the same
   declaration the quarter picker takes it from, so the two stay the same height. */
.alt-app .okr-team-switch select{ width:auto; min-width:130px; }

/* The middle group takes the space — `min-width:0` lets it shrink before the row breaks;
   otherwise the utility cluster is pushed onto a second line instead.
   `align-items:flex-end`, not `center`: some controls here are two-row captioned fields
   (View, Group by, Layout) and the rest are one row tall, so bottom-aligning lands every
   control on one baseline regardless of caption height — the same rule `.at-ctx` makes on
   the team board. */
.alt-app .okr-ctx-controls{
  display:flex; align-items:flex-end; gap:var(--a-2); flex-wrap:wrap;
  flex:1 1 420px; min-width:0;
}
/* The utility cluster keeps the right-hand end at every width above the phone breakpoint.

   `align-self:flex-end`, owner request: *"align the buttons of reports, help and pin with the filters & more to where the reports, help and pin match the bottom of filter&more button."*
   `.okr-ctx-controls` is the row's tallest item and bottom-anchors its OWN children, so without
   this the cluster's box was centred in that same flex line instead — the fix is where the box
   sits in the row, not how its children sit in the box, the same class of bug
   `.okr-team-switch`'s own `align-self:flex-start` already corrects two rules up. */
.alt-app .okr-ctx-util{
  display:flex; align-items:center; gap:2px; flex:0 0 auto; margin-left:auto; align-self:flex-end;
}

/* The export control is one `.a-btn.ghost` — icon, label, trailing chevron — as three ordinary
   flex children; it needs no split-button rules of its own. `.a-btn:not(.icon) > svg` sizes
   both glyphs and the base rule's own gap separates them, and the cluster's standing
   `gap:2px` above already separates this control from the help mark beside it. */

/* The suite's hairline, so a run of controls reads as groups rather than as one long row. */
.alt-app .okr-ctx-rule{
  width:1px; align-self:stretch; margin:3px 2px; background:var(--a-line); flex:0 0 auto;
}
/* Shorter than what it divides, deliberately — the owner's preference after seeing both:
   *"Adjust the vertical dividers so they are as tall as the controls between period and filters."*, then *"Shorten the height of the vertical divider pointed out with arrows."*
   `align-self:stretch` gives each rule its own flex line's height, which is what a fixed
   18px/inset-6px override needs to sit shorter than the controls on every line — because
   `.okr-ctx-controls`'s own `align-items:flex-end` bottom-anchors every control regardless of
   which line it wraps to.

   Scoped to `.okr-ctx-controls` — the utility cluster keeps its own `margin:3px 2px` geometry;
   okrs.html's override there sets only `margin-inline`, and okr-layout.test.js asserts it
   declares no pixel margin of its own. */
.alt-app .okr-ctx-controls > .okr-ctx-rule{ align-self:flex-end; height:18px; margin-block:0 6px; }

/* The quarter picker stays a multi-select, because a key result belongs to one quarter and the
   work somebody wants to see rarely does. `size="1"` keeps it one row tall until it is opened. */
.alt-app .okr-ctx-cycles{ width:auto; min-width:160px; max-width:220px; }

/* Bounded at both ends, deliberately: the ceiling stops `flex:1 1` growing a search box into
   every pixel the other controls leave, for a query that is rarely more than a word; the floor
   stops it collapsing to a stub when the row is full. The basis sits below the ceiling rather
   than fixed, so the box a reader sees on a roomy screen is unchanged and the width is only
   given up where the alternative is a broken row. */
.alt-app .okr-ctx-search{ flex:1 1 200px; min-width:170px; max-width:340px; }
.alt-app .okr-ctx-search .a-input{ height:var(--a-ctl); }

/* Clear all is the filter indicator as well as the action — okrRenderControls() reveals it
   whenever any filter or the search is narrowing the board — so it is coloured like a live
   state rather than like one more grey button. */
.alt-app .okr-ctx-clear{
  border-color:var(--a-blue); color:var(--a-blue-text); background:var(--a-blue-soft);
}

/* ---- Filters: progressive disclosure, with no second popover implementation ----
   Opened through JS/components/popover.js as a plain `<button>` rather than a `<details>`, for
   outside-click dismissal — see okrs.html's own comment on `#okrFiltersPop` for the reasoning. */
.alt-app .okr-filters-pop{
  position:absolute; top:calc(100% + 6px); left:0; z-index:var(--z-float);
  /* Owner: *"create standard padding in this control. The controls are too tight."* `--a-4`
     is the token ladder's own next step up from what was here, and matches the space this
     floating panel needs now that it has three stacked controls and no page furniture to
     borrow breathing room from. `.a-field`'s own label-to-control gap is unchanged; what
     moved is the space between fields and around the group. */
  /* The spacing is stated as adjacent-sibling margins, not `gap` — this surface is opened
     through JS/components/popover.js, which sets an inline `display:block` that always beats
     a stylesheet `display:flex`, so a `gap` declared here could never take effect. Margins
     work whether this box ends up block or flex, so the panel stays correct even if the
     component stops imposing a display. Owner, after the step-up above had already shipped
     and the gap still was not applying: *"the controls need standard padding. They are too tight."*
     Fixing popover.js itself is out of proportion — it is loaded by six pages and
     opened by nine modules, and this is the only surface whose sheet declares a display for
     it to override — but the next popover wanting flex or grid will lose it the same way,
     silently. */
  min-width:240px; padding:var(--a-4);
  background:var(--a-float); border:1px solid var(--a-line-strong);
  border-radius:var(--a-r); box-shadow:var(--a-shadow);
}
/* At the right-hand edge of a narrow window the panel would hang off the page. */
@media (max-width:820px){
  .alt-app .okr-filters-pop{ left:auto; right:0; }
}
.alt-app .okr-filters-pop > * + *{ margin-top:var(--a-4); }
.alt-app .okr-filters-pop select{ width:100%; }

/* ================= 3 · THE SUITE'S CONTROL LANGUAGE, ON THE CLASSIC COMPONENTS ================= */

/* ---- buttons ----
   `.btn` is what every shared OKR module renders: the editor's Save, the detail panel's actions,
   Re-evaluate, the empty states' links, the settings dialog's rows. One rule pair gives all of
   them the suite's button rather than thirty markup edits in files this page does not own. */
.alt-app .btn{
  height:var(--a-ctl); padding:0 var(--a-3); gap:6px;
  font-family:var(--a-body); font-size:13px; font-weight:600; line-height:1;
  background:var(--a-raised); color:var(--a-text);
  border:1px solid var(--a-line-strong); border-radius:var(--a-r-sm);
}
.alt-app .btn:hover:not(:disabled){ border-color:var(--a-line-strong); color:var(--a-text); }
.alt-app .btn.small{ height:26px; padding:0 9px; font-size:12px; }
.alt-app .btn.primary,
.alt-app .btn.primary:hover:not(:disabled){ background:var(--a-blue-fill); border-color:transparent; color:#fff; }
.alt-app .btn.danger{ background:transparent; border-color:var(--a-red); color:var(--a-red); }
.alt-app .btn.danger:hover:not(:disabled){ background:var(--a-red-soft); }
/* Hover must not outrank the state: `.btn:hover` above matches at higher specificity than this
   rule did, so a pressed toggle under a resting pointer showed only a background change until
   the mouse moved away. Specificity raised to match keeps the full lit state on press. */
.alt-app .btn.active,
.alt-app .btn.active:hover:not(:disabled){ background:var(--a-blue-soft); border-color:var(--a-blue); color:var(--a-blue-text); }
.alt-app .btn.icon-only{ width:var(--a-ctl); padding:0; }
.alt-app .btn:focus-visible,
.alt-app .a-btn:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }

/* ---- fields ----
   The same declaration okrs.html's own <style> block makes for the page, in the suite's terms;
   it wins because this file is loaded last. Every select and input the OKR modules render is
   covered. `:not(.a-input)` is the point of this whole section: these rules dress a field that
   arrives in classic vocabulary, from files this page does not own, in the suite's control
   language. A field that already carries `.a-input`, `.a-select` or `.a-textarea` is already
   suite vocabulary — alt-components.css is its canonical home.

   Without the exclusion this rule did not restate the component, it OUTRANKED it: a bare
   `input[type=search]` here beats the component rules that reserve the magnifier's and the
   ⌘K keycap's space, which collapsed the top bar's search to a flat box with the glyph drawn
   over the first character. The same collision reproduced on any shell page whose own sheet
   carried the same unexcluded rule; `_docs/tests/search-field-chrome.test.js` now checks every
   stylesheet the shell pages load rather than relying on one page being remembered.

   Fixed here, not by raising `.a-search .a-input`'s specificity — that would make one page's
   accident the shared component's permanent shape, the escalation sys_design-system.md §2
   exists to prevent. */
.alt-app input[type=text]:not(.a-input),
.alt-app input[type=email]:not(.a-input),
.alt-app input[type=password]:not(.a-input),
.alt-app input[type=date]:not(.a-input),
.alt-app input[type=number]:not(.a-input),
.alt-app input[type=tel]:not(.a-input),
.alt-app input[type=search]:not(.a-input),
.alt-app input[type=url]:not(.a-input),
.alt-app select:not(.a-select),
.alt-app textarea:not(.a-textarea){
  font-family:var(--a-body); font-size:13px;
  background:var(--a-bg); color:var(--a-text);
  border:1px solid var(--a-line-strong); border-radius:var(--a-r-sm);
  height:var(--a-ctl); padding:0 10px;
}
.alt-app textarea:not(.a-textarea){ height:auto; padding:8px 10px; line-height:1.5; }
/* A multi-select with size>1 has to keep its rows; height is the single-row control's rule. */
.alt-app select[multiple][size]:not([size="1"]){ height:auto; padding:6px 8px; }

/* ---- and the other half of the same collision: the PAGE's own <style> block ----
   Excluding `.a-input` above stops this file fighting the component; it does not stop
   okrs.html's inline block doing so, which outranks a bare class by one attribute selector
   (sys_design-system.md §2). So this page alone wore the classic field's border, radius and
   background on every `.a-input` that is an `<input>`, restated here. `.a-select` and
   `.a-textarea` were never affected — the inline block reaches them through bare type
   selectors, which lose to a class — so only `.a-input` needs restating.

   Only the properties nothing else claims: `.a-search .a-input` and `.a-top-search .a-input`
   are the same specificity and load earlier, so declaring height, padding-left, padding-right
   or width here would win the tie and is deliberately omitted — that tie is what put the
   magnifier over the search text in the first place. `width:100%` still leaks from the inline
   block; left alone since no measured defect follows from it.

   The focus border survives by specificity, not by luck: `.a-input:focus` ties this rule, but
   `.alt-app input:focus` below outranks both — keep that rule below this one. */
.alt-app .a-input{
  background:var(--a-bg);
  border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  padding-top:0; padding-bottom:0;
}

.alt-app input:focus,
.alt-app select:focus,
.alt-app textarea:focus{ outline:none; border-color:var(--a-blue); }
.alt-app input:focus-visible,
.alt-app select:focus-visible,
.alt-app textarea:focus-visible{ outline:2px solid var(--a-ring); outline-offset:1px; }
.alt-app ::placeholder{ color:var(--a-faint); opacity:1; }

/* ---- the segmented control ----
   This page's three segmented controls wear `.at-tabs`/`.at-tab`, the suite's boxed tab track
   from CSS/alt/alt-components.css — the same control team_board.html's View strip uses, rather
   than a local pill with its own solid-fill lit state. CSS/okr.css still declares `.okr-seg`
   for markup nothing on this page emits any more; reported rather than deleted here since that
   sheet is loaded by five pages. */

/* ---- the captioned field that holds one ----
   The track is not the control; the caption above it is half of it. `.a-field` supplies the
   column and caption, this says only how the field behaves in this row: `flex:0 0 auto`
   because a segmented control has a content width and must not be the item the row squeezes
   — the search box is, and says so itself. */
.alt-app .okr-seg-field{ flex:0 0 auto; }

/* ---- PERIOD, the quarter picker's own captioned field ----
   Same `flex:0 0 auto` and reason. Width rules stay on the select below since they are about
   the picker, not the field — but flex is on the field, because the field is what lays the
   row out. */
.alt-app .okr-cycle-field{ flex:0 0 auto; }

/* ---- THE CAPTIONS LEFT-ALIGN TO THEIR CONTROLS ----
   The owner's second word stands over the first.
   First: *"align the labels to the middle of each selection like how Team is aligned center"* — tried as `text-align:center`.
   Seeing it rendered: *"Instead of center, which is not standard, align labels to the left of the control for all labels with the arrow pointed to them... All labels should align to the left side of the control."*
   Team moved with them — see `align-items:flex-start` on `.okr-team-switch` above, a different declaration for a different cause.

   Declared rather than left to `.a-field`'s own default (which already computes `start`),
   because a value decided twice by hand is a value that gets reversed by accident if nothing
   pins it — okrs-chrome.test.js pins this one. Written against this page's own field classes
   rather than `.a-field` directly, since a `.a-field > span` rule here would also reach the
   Filters popover's fields, which share the class but not this row's decision. */
.alt-app .okr-seg-field > span,
.alt-app .okr-cycle-field > span{ text-align:left; }

/* ---- the band heading ----
   THE SCALE IS `.a-sec-h`'s, in CSS/alt/alt-components.css, and is deliberately NOT restated
   here: 10px/700/.1em uppercase is the suite's section label and a second declaration of it is
   a second thing to keep in step. What is this page's business is how much air it takes above
   the band it names — an <h2> would otherwise inherit a heading margin from CSS/okr.css. */
.alt-app .okr-band-h{ margin:0 0 var(--a-2); }

/* ---- the health chip ----
   SHAPE ONLY. Every colour below is still --okr-*, resolved in CSS/okr.css from the canonical
   palette — the same red, orange, green, accent, purple and neutral the suite's own semantic
   roles resolve to. This makes the pill the suite's chip: the same height, radius, letter
   spacing and weight as `.a-chip`, so a status on this page and a status on the team board read
   as one system. */
.alt-app .okr-pill{
  font-family:var(--a-body); font-size:11px; font-weight:600; letter-spacing:.02em;
  height:20px; padding:0 8px; border-radius:var(--a-r-pill);
}

/* ---- surfaces: cards, groups, panels, dividers ---- */
.alt-app .okr-band{
  background:none; border:none; border-radius:0;
  padding:0 2px var(--a-2); margin:0 0 var(--a-2);
}
/* The ladder is a caption now rather than the contents of a card. */
.alt-app .okr-band .okr-band-ladder{ margin:0; }

.alt-app .okr-summary,
.alt-app .okr-group,
.alt-app .okr-card,
.alt-app .okr-empty{
  background:var(--a-panel); border:1px solid var(--a-line); border-radius:var(--a-r);
}
.alt-app .okr-group{ margin-bottom:var(--a-3); }
.alt-app .okr-group-head:hover,
.alt-app .okr-obj-head:hover{ background:var(--a-raised); }
.alt-app .okr-group-body,
.alt-app .okr-obj{ border-color:var(--a-line-soft); }
.alt-app .okr-group-rule{ background:var(--a-line-soft); }
.alt-app .okr-stat{ border-radius:var(--a-r-sm); border-color:var(--a-line); }
.alt-app .okr-stat:hover{ border-color:var(--a-line-strong); }
.alt-app .okr-stat.active{ border-color:var(--a-blue); background:var(--a-blue-soft); }
.alt-app .okr-kr{ border-radius:var(--a-r-sm); }

/* THE DIALOGS KEEP THEIR WORKFLOW AND TAKE THE SUITE'S SURFACE. The objective editor, the key
   result editor, the detail panel and the settings dialog are the same components doing the same
   things — this is the card they are drawn on, matching CSS/alt/alt-shared-dialogs.css so a
   dialog opened from this page and one opened from the team board are the same object. */
.alt-app .okr-modal-pane{
  background:var(--a-panel); border:1px solid var(--a-line-strong);
  border-radius:var(--a-r-lg); box-shadow:var(--a-shadow-lg);
}
.alt-app .okr-modal-head{ border-bottom:1px solid var(--a-line); }
.alt-app .okr-modal-head h2{ font-family:var(--a-display); }
.alt-app .okr-modal-foot{ border-top:1px solid var(--a-line); }

/* ---- the list head ----
   Keeps every control it had — Sort, Hide completed, Assigned to me, Re-evaluate and the two
   fold pairs act on the objectives list and stay with it, put there deliberately (see okrs.html).
   This only sets the row on the suite's spacing so it reads as the list's caption. */
.alt-app .okr-list-head{
  gap:var(--a-2); padding:0 2px;
  /* The clean break between the header stack and the board: now that only the context strip
     and the band pin, this row is the caption atop the scrolling content and needs clear space
     below it so the list does not read as starting behind its own heading. Deliberately not a
     rule line — the `.stuck` shadow under the pinned band is already the page's one separator. */
  margin:var(--a-4) 0 var(--a-4);
}
.alt-app .okr-sort > span{
  font-size:10px; font-weight:700; letter-spacing:.09em; color:var(--a-dim);
}
.alt-app .okr-list-head .okr-sort select{ height:26px; font-size:12px; padding:0 8px; }
.alt-app .okr-list-title{ font-family:var(--a-display); font-size:15px; }
.alt-app .vrule{ background:var(--a-line); }

/* The hairline between the two folding axes is not styled here, deliberately: a vertical
   hairline divides two controls on one line, and when they wrap apart it divides nothing and
   reads as a rendering fault. A breakpoint cannot express "did these two land on the same
   line" — that is an outcome of flex-wrap over every control in the row — so
   okrFoldRuleWrap() in JS/pages/okrs.js asks it after layout instead. Do not reintroduce a width rule here. */

/* ================= 4 · PINNING =================
   #okrPinHead is one sticky box holding the toolbar, so pinning pins the toolbar with the
   summary and the list head.

   It has to clear the shell, which is not a fixed height: `.a-top` is itself sticky at top:0
   in the same scroll root, so this header needs a real offset or the two draw over each
   other. `--okr-shell-h` is written by okrs.html from the bar's own measured height, kept in
   step by a ResizeObserver; 56px is only the fallback.

   It sits below the shell in the stack for the same reason — two sticky boxes at the same z
   with overlapping edges is a coin toss about which one the reader sees, and the shell is the
   outer chrome. Content drawn above a pinned header is never a z-index fault here — read the
   `top` note below before reaching for one. */
.alt-app .okr-pinhead{ padding:0; margin:0; }
.alt-app .okr-pinhead.pinned{
  /* One `top` declaration in the whole file. A media query adds no specificity, so a second
     `top:0` elsewhere at the same specificity would win by source order alone and silently
     reintroduce the gap this is here to close. Declaring it once and letting the breakpoint
     below re-point the INPUT retires that race instead of re-running it; a second `top:` on
     this selector is now a test failure. */
  --okr-pin-top:var(--okr-shell-h, 56px);
  top:var(--okr-pin-top);
  z-index:calc(var(--z-sticky) - 1);
  background:var(--a-bg);
  /* The pinned header may not eat the screen it is a header for. The fraction is measured from
     what is actually left, not the window — the shell is above the header at every width, so
     the cap is 60% of `100dvh - --okr-shell-h`, not of the full viewport, or it charges for the
     shell bar twice. `vh` first as the fallback for an engine without `dvh`. */
  /* The cap is a re-pointable input for the same reason `top` is: a second `max-height` on this
     selector races on source order, which okr-pin-header.test.js fails the build over. The
     phone block re-points `--okr-pin-cap`; it does not re-declare max-height. */
  --okr-pin-cap-vh:calc(60vh - 0.6 * var(--okr-shell-h, 56px));
  --okr-pin-cap:calc(60dvh - 0.6 * var(--okr-shell-h, 56px));
  max-height:var(--okr-pin-cap-vh);
  max-height:var(--okr-pin-cap);
}

/* At 1024 and up the pin offset is zero, because §1 moved the scroll root into main.okr-main,
   a box that already begins underneath the shared bar — pinning to its top would spend the
   bar's height twice. Below 1024 the document is the root and `.a-top` is sticky within it, so
   the offset is genuinely wanted there, which is why it is the default above. This block is
   placed AFTER that default on purpose — equal specificity, so source order decides the
   winner, and moving it above brings the offset silently back. */
@media (min-width:1024px){
  .alt-app .okr-pinhead.pinned{ --okr-pin-top:0px; }
  /* The page's top rhythm lives here now, since §1 took it off the scrollport. Inside the
     header rather than above it, so `--a-bg` covers it and the list cannot appear in it. Given
     to `.okr-pinhead` rather than `.pinned` since this spacing does not depend on pin state.
     Placed after `padding:0` above for the same source-order reason this section exists. */
  .alt-app .okr-pinhead{ padding-top:var(--a-3); }
}
.alt-app .okr-pinhead.pinned.stuck{ border-bottom:1px solid var(--a-line); box-shadow:var(--a-shadow-sm); }

/* ================= 5 · RESPONSIVE =================

   THE SAME THREE STOPS THE SUITE USES (CSS/alt/alt-responsive.css): the desk, the laptop, the
   phone. Nothing is removed at any of them — the toolbar reflows, and every control the wide
   layout offers is still on screen and still reachable. */

/* Laptop. The utility cluster gives up its right-hand anchor and joins the flow, so the middle
   group gets a full line of its own rather than three controls per line. */
@media (max-width:1023px){
  .alt-app .okr-ctx{ gap:var(--a-2); }
  .alt-app .okr-ctx-controls{ flex:1 1 100%; order:3; }
  .alt-app .okr-ctx-util{ order:2; }
  .alt-app .okr-ctx-search{ flex:1 1 200px; max-width:340px; }
}

@media (max-width:820px){
  .alt-app main.okr-main{ padding:var(--a-2) var(--a-3) var(--a-5); }
  .alt-app .okr-ctx{ padding:var(--a-2); }
}

/* Phone. The name and the team stack, the controls wrap into as many rows as they need, and the
   quarter picker and the search each take a full line so neither is a 90px stub. The segmented
   controls stay: List and Kanban both work at this width and hiding one would be removing a
   capability rather than adapting to a screen. */
@media (max-width:639px){
  /* ---------- THE HEADER DOES NOT PIN ON A PHONE ----------
     The 60% cap is deliberately generous for a desktop reference panel, but the same fraction
     of a phone screen leaves no room for the board it is a header for. So the pin is dropped
     at this width rather than shrunk — making it shorter would mean choosing which of the
     team, the filters and the summary a phone reader may keep, and there is no room to hold
     any of them open. Below 640 the document is the scroll root anyway, so the header simply
     scrolls away and back like every other block on the page.

     The preference is not overwritten, only unused here: `okrPrefs.pinHeader` still reads
     true and the same account on a laptop still gets its pinned header. A responsive rule may
     decide there is no room; it may not decide what somebody wants. */
  .alt-app .okr-pinhead.pinned{
    position:static; box-shadow:none; border-bottom:0;
    /* The input, not the declaration — see §4 · PINNING. Static needs no cap. */
    --okr-pin-cap-vh:none; --okr-pin-cap:none;
  }
  .alt-app .okr-ctx-id{ flex:1 1 100%; }
  .alt-app .okr-ctx-title{ font-size:16px; white-space:normal; }
  .alt-app .okr-team-switch{ flex:1 1 100%; }
  /* `width:100%`, not `flex:1 1 auto`: the field is a column now, so a flex-grow on its child
     grows it downwards instead of filling the phone's row. Width is the axis this needs. */
  .alt-app .okr-team-switch select{ width:100%; min-width:0; }
  /* The field takes the row and the select fills the field — same pair, same reason as the
     team switch above: the picker is a column now, so flex on the select would grow it
     downwards instead of widening it. Flex belongs to the field, width to the control. */
  .alt-app .okr-cycle-field{ flex:1 1 100%; }
  .alt-app .okr-ctx-cycles{ width:100%; min-width:0; max-width:none; }
  /* The ceiling is lifted here only: on a phone the row is one control wide, so the 340px cap
     would leave empty bar beside a search box that is already the whole line. The floor stays. */
  .alt-app .okr-ctx-search{ flex:1 1 100%; max-width:none; }
  .alt-app .okr-ctx-rule{ display:none; }
  /* `min-width:0` is what still visibly acts here, loosening the 240px floor on a phone;
     `left`/`right` lose to the inline position `positionPopover()` writes on open. */
  .alt-app .okr-filters-pop{ left:0; right:0; min-width:0; }
}

/* ================= 6 · MOTION =================
   alt-tokens.css already zeroes --a-quick and the --dur-* family under `.alt-app` for anybody who
   asked for less movement, so every transition written through a token is answered. The only
   thing here that is not is the details disclosure, which has none. */

/* ================= 7 · THE OUTSIDE-THE-RANGE LIST =================
   JS/features/okr-board.js — okrOutsidePanelHtml() and the "+N outside" badge it hangs off.
   The badge's own look stays in CSS/okr.css; this file adds only what turning it into a
   control needs, and the panel it opens.

   Scoped `body.alt-app`, not `.alt-app`: the panel's host is a div appended directly to
   `<body>` (see okrOutsideHost()), so it is a CHILD of the element carrying `.alt-app` rather
   than a descendant of anything inside the page — the same selector CSS/okr-quarter-grid.css
   uses for the same arrangement, keeping the --a-* role tokens in scope out there.

   No new surface and no new colour: `.cfg-popover` is the panel, `.a-chip` with a `.n.a-mono`
   figure is the count, `.okr-dot` with its `st-*` is the health marker every other OKR surface
   draws. Everything below is layout. */

body.alt-app .okr-outside-pop{
  /* Wider than `.cfg-popover`'s 236px: these rows carry a measure's TITLE, and a title wrapped
     to four words a line is a list nobody scans. Capped against the viewport so the phone gets
     a panel with gutters rather than one clamped by positionPopover() at the last moment. */
  width:min(360px, calc(100vw - 32px));
  padding:var(--a-3);
  /* A LONG TAIL SCROLLS RATHER THAN OVERFLOWING THE SCREEN. positionPopover() measures
     offsetHeight after display:block, so a capped panel is positioned against its real height
     and flips above the badge correctly instead of hanging off the bottom. */
  max-height:min(60vh, 440px); overflow-y:auto;
  display:flex; flex-direction:column; gap:var(--a-3);
  font-family:var(--a-body);
}
body.alt-app .okr-outside-pop:focus{ outline:none; }
body.alt-app .okr-outside-pop:focus-visible{ outline:2px solid var(--a-ring); outline-offset:-2px; }

body.alt-app .okr-outside-head{ display:flex; flex-direction:column; gap:2px; }
/* Two text tiers, not three — a measurement, not a taste. This caption, the footnote and the
   archived marker were all on `--a-faint`, which measures 4.13:1 dark / 4.33:1 light on this
   panel against WCAG 1.4.3's 4.5:1; `--a-dim` measures 6.5:1+. Hierarchy here is carried by
   size, weight and case instead, so nothing is lost by the move. */
body.alt-app .okr-outside-title{
  margin:0; font-family:var(--a-display);
  font-size:11px; font-weight:700; letter-spacing:.4px; text-transform:uppercase;
  color:var(--a-dim);
}
/* The objective these belong to. Two lines at most — it is context for the list, not the
   heading of it, and a five-line title would push the measures under the fold. */
body.alt-app .okr-outside-obj{
  margin:0; font-size:13px; font-weight:600; line-height:1.35; color:var(--a-text);
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden;
}

body.alt-app .okr-outside-group{ display:flex; flex-direction:column; gap:var(--a-1); }
/* The quarter is the heading, because the quarter is what was asked for. Not sticky,
   deliberately — a sticky caption needs an opaque background of its own, and `.cfg-popover`'s
   surface is a token this file must not restate. The lists here are a handful of measures, so
   losing the caption on a rare long scroll costs less than a caption that sometimes goes
   transparent. */
body.alt-app .okr-outside-qtr{
  margin:0; padding:0 0 var(--a-1);
  display:flex; align-items:center; gap:var(--a-2);
  font-size:11px; font-weight:700; letter-spacing:.3px; text-transform:uppercase;
  color:var(--a-dim);
  border-bottom:1px solid var(--a-line-soft);
}
body.alt-app .okr-outside-qtr-l{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Pushed to the far end; `.a-chip` already owns everything else about how it looks. */
body.alt-app .okr-outside-n{ margin-left:auto; flex:0 0 auto; }

body.alt-app .okr-outside-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
body.alt-app .okr-outside-row{
  display:flex; align-items:flex-start; gap:var(--a-2);
  padding:var(--a-2) 0;
  border-bottom:1px solid var(--a-line-soft);
}
body.alt-app .okr-outside-row:last-child{ border-bottom:0; }
/* The dot is a marker on a text row, not a bullet centred on a two-line block — nudged down to
   sit on the first line's baseline the way the List row's own does. */
body.alt-app .okr-outside-row .okr-dot{ flex:0 0 auto; margin-top:4px; }
body.alt-app .okr-outside-kr{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; }
body.alt-app .okr-outside-kr-title{ font-size:12.5px; line-height:1.4; color:var(--a-text); }
body.alt-app .okr-outside-kr-meta{
  display:flex; flex-wrap:wrap; gap:var(--a-1) var(--a-2);
  font-size:11px; line-height:1.4; color:var(--a-dim);
}
/* A long name ellipses rather than wrapping under itself: the meta line is a second, quieter
   line under the measure's title, and a name that takes two of its own turns one row into
   three. Everything else about how it reads it inherits from `.okr-outside-kr-meta`. */
body.alt-app .okr-outside-owner{ max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
body.alt-app .okr-outside-arch{
  color:var(--a-dim); text-transform:uppercase; letter-spacing:.3px; font-weight:600;
}
/* Archived measures are still counted by the badge, so they are still listed — quietly, so the
   eye lands on the live ones first. */
body.alt-app .okr-outside-row.is-archived .okr-outside-kr-title{ color:var(--a-dim); }
body.alt-app .okr-outside-pct{
  flex:0 0 auto; font-size:12px; font-weight:600; color:var(--a-text);
  font-variant-numeric:tabular-nums; padding-top:1px;
}

body.alt-app .okr-outside-foot{
  margin:0; padding-top:var(--a-1);
  border-top:1px solid var(--a-line-soft);
  /* IT IS THE ONE INSTRUCTION ON THE PANEL — what to do about what you are looking at — so it
     is the last text here that may sit below AA. See the tier note above. */
  font-size:11px; line-height:1.45; color:var(--a-dim);
}

/* ---------- the badge, once it is a control ----------
   Nothing here changes its box — okr.css gives `.okr-hidden-krs` its padding, border, radius
   and font, and that footprint is load-bearing since the Kanban card's title shares its row at
   narrow widths. This adds only a pointer, a hover that moves the existing border's colour, and
   a focus ring drawn with `outline`, outside layout entirely. Beats okr.css's `cursor:default`
   on specificity and on load order (this file loads after it — see okrs.html). */
.alt-app .okr-hidden-krs.is-pressable{ cursor:pointer; }
.alt-app .okr-hidden-krs.is-pressable:hover,
.alt-app .okr-hidden-krs.is-pressable[aria-expanded="true"]{ border-color:var(--warn-text); }
.alt-app .okr-hidden-krs.is-pressable:focus-visible{
  outline:2px solid var(--a-ring); outline-offset:2px;
}

@media (max-width:719px){
  body.alt-app .okr-outside-pop{ width:min(320px, calc(100vw - 24px)); max-height:min(58vh, 380px); }
}

/* ---- "What this counts" — the explanation behind Objectives in view ----
   The figure counts an objective that is filed in the quarter OR has a key result due during
   it, so it can legitimately exceed the number filed there — JS/pages/okrs.js, okrInViewPop().

   `body.alt-app`, everything else borrowed, for the same reasons the `.okr-outside-pop` block
   above states: the panel's host is a div appended straight to `<body>`, so it is a child of
   the element carrying `.alt-app`. `.cfg-popover` is the surface and `.alt-app .cfg-popover`
   (alt-message-center.css) gives it the suite's float treatment.

   Two text tiers, not three, for the same measurement recorded above: the caption takes
   `--a-dim` and the emphasised words take `--a-text`, the same pair the outside-the-range
   panel settled on. */
body.alt-app .okr-inview-pop{
  /* Wider than `.cfg-popover`'s 236px — that is a picker width and this is three sentences.
     Capped against the viewport so the phone gets gutters rather than a panel positionPopover()
     clamps at the last moment. */
  width:min(320px, calc(100vw - 32px));
  padding:var(--a-3);
  font-family:var(--a-body);
}
body.alt-app .okr-inview-pop:focus{ outline:none; }
body.alt-app .okr-inview-pop:focus-visible{ outline:2px solid var(--a-ring); outline-offset:-2px; }
body.alt-app .okr-inview-title{
  margin:0 0 var(--a-2); font-family:var(--a-display);
  font-size:11px; font-weight:700; letter-spacing:.4px; text-transform:uppercase;
  color:var(--a-dim);
}
body.alt-app .okr-inview-p{
  margin:0 0 var(--a-2); font-size:12px; line-height:1.5; color:var(--a-dim);
}
body.alt-app .okr-inview-p:last-child{ margin-bottom:0; }
/* The words carrying the rule — "filed in", "or", "due during". The loud tier rather than a
   second colour: this is an explanation, not a warning. */
body.alt-app .okr-inview-p strong{ font-weight:600; color:var(--a-text); }

/* ================= 8 · "NOTHING MATCHES" NAMES THE FILTERS =================
   JS/features/okr-board.js — okrNothingMatchesHtml().
   The panel now carries the count and the list of filters that produced it, which need to
   read as a caption over a list rather than as two more paragraphs the same weight as
   `.okr-empty p`'s own sentence. The list is centred like the rest of the panel, but its items
   are chips rather than bullets — a bulleted list in a centred box hangs its markers in the
   middle of nowhere. `.a-chip`'s recipe is not reused since these are not interactive and must
   not read as pressable; the one pressable thing in this panel is the button underneath. */
.alt-app .okr-empty-why{
  /* Overrides .okr-empty p's 16px bottom margin: this is the caption OF the list below it. */
  margin:0 auto 6px; font-size:12px; color:var(--a-dim);
}
.alt-app .okr-empty-filters{
  list-style:none; margin:0 auto var(--a-4); padding:0;
  display:flex; flex-wrap:wrap; gap:var(--a-1) var(--a-2); justify-content:center;
  max-width:420px;
}
.alt-app .okr-empty-filters li{
  font-size:12px; line-height:1.5; color:var(--a-text);
  background:var(--a-raised); border:1px solid var(--a-line);
  border-radius:var(--a-r-pill); padding:2px 10px;
  /* A pasted search term is the one item here that can be long. It wraps inside its own chip
     rather than widening the row past the panel's measure. */
  max-width:100%; overflow-wrap:anywhere;
}

/* ================= 9 · THE PUSH INDICATOR =================
   JS/pages/okrs.js — okrPushChipHtml(), drawn in the objective row's badge cluster, on the
   Kanban card and on a key-result row.

   No new surface, no new colour, no new geometry: `.a-chip` is the whole look, so it cannot
   drift from every other neutral chip in the suite — the same primitive `.okr-outside-n` wears.
   Not `.a-okr-pill st-<token>`, which reserves status colour for health bands and a push is not
   one — an objective can be On Track and have been pushed twice. Not `.okr-hidden-krs` either,
   whose amber IS its meaning; a moved date is a fact about history, not a warning about now.
   Everything below is the three things placing it in a row actually needs — no colour, no type. */

/* Must not shrink: both host rows have a flex-growing sibling, so without this the chip is
   what gives way when a long title takes the row, collapsing "Pushed twice" to "Pushed tw…". */
.alt-app .okr-push-chip{
  flex:0 0 auto;
  /* `.a-chip` clamps to 170px with an ellipsis, right for a tag somebody typed; this chip's
     text is never user-supplied, so that clamp could only ever truncate a label that fit. */
  max-width:none;
  /* Matches the two pills it sits between — `.a-chip` is 2px (6px on a phone) taller than its
     neighbours, which stood it proud of a cluster meant to read as one row of badges.
     Opting out of the touch floor is not a workaround: this is an inert `<span>` with no role
     and no tab stop, so `.a-chip`'s own "a chip is only a target when it is pressable, `.a-chip`
     is also a label" distinction applies — a 26px thumb minimum does not apply to it. Everything
     that makes it a chip still comes from `.a-chip`, untouched. Wins on specificity and on load
     order (this file loads after alt-responsive.css). */
  height:20px; min-height:0;
}
.alt-app .okr-push-chip svg{ flex:0 0 auto; }

/* On a key-result row it sits on the first line, beside the numbers — measured, not guessed:
   `.okr-kr-head` is `align-items:start`, so the chip centres 2px low against the figures it
   sits beside unless pulled up. The negative margin has room inside `.okr-kr`'s own padding at
   both densities. This is the only one of the three clusters that needs the nudge; the other
   two are `align-items:center` and need no correction. */
.alt-app .okr-kr-head .okr-push-chip{ margin-top:-2px; }

/* The Kanban card keeps the whole label: `.okr-card-side` is the one cluster of the three that
   wraps, so the chip drops to its own line instead of competing with the title for the row.
   The word is not split into a droppable span the way `.okr-hidden-krs-l` is, because "Pushed"
   cannot lose its verb — a chip reading only "2 quarters" says nothing about which way it went,
   and the direction is the whole point. */

/* ---------- A CREDIT IS NOT A WARNING, AND IT IS NOT A SECOND CHIP ----------
   This is a SIGNED measure: a period that ended up later is "Pushed 1 quarter", one that ended
   up earlier is "Pulled back 1 quarter", and one that returned to where it started says
   nothing. Owner, on why: *"so people get credit for bringing things in ahead of time"* — a
   credit must not read like a warning. Full reasoning and the audit trail live in
   JS/services/okr-push-count.js's header.

   A credit is the same chip in a different colour: same geometry, only the border and text
   change, so the two sit level and read as one family. The colour is the design system's, not
   invented here — `--a-green` is exactly what `.a-chip-st.st-complete` resolves to for a
   positive signal on a chip, so status stays a modifier of `.a-chip`, never a second chip.
   `st-complete` itself is not reused: that class name on a chip about an earlier date would say
   "this is finished", which is a lie in the markup a DOM reader is owed better than.

   Measured against the chip's own ground: `--a-green` is 5.4:1 dark / 5.3:1 light, above AA for
   text this size (`_docs/tests/okr-push-chip-probe.py`, both widths and themes). And the colour
   is never the only signal — the verb and the arrow carry direction on every surface, which is
   also why the report and print surfaces emit no credit colour at all: a hue does not survive
   paper or a photocopy. */
.alt-app .okr-push-chip.is-credit{
  border-color:var(--a-green);
  color:var(--a-green);
}

/* ================= THE PORTFOLIO GRID'S OWN CHOOSER =================
   Draws the control that decides which rows and columns "OKRs by area, by quarter" shows
   (okrGridShowHtml(), JS/features/okr-overview.js). The card's other selected-looking thing,
   the blue wash on cells in CSS/okr.css, is the PAGE filter, and the two must never resolve to
   the same picture — so nothing here is blue, deliberately, since that hue already means "in
   the filter above" elsewhere on this page. A shown chip is the card's neutral raised
   treatment; a hidden one is dashed and dimmed, the vocabulary `.okr-cell.empty` already uses
   for "there is nothing here".

   Lives here rather than in CSS/okr.css since the surface it draws on exists on exactly one
   page — okr-overview.js is loaded by okrs.html and nothing else — keeping the base sheet free
   of a component only the suite renders. */

.alt-app .okr-grid-show{
  display:flex; align-items:center; flex-wrap:wrap; gap:var(--a-2);
  /* On .okr-card-sub's own 12px text indent, so the caption, this control and the table read
     as one left edge rather than three. */
  padding-left:12px; margin:0 0 var(--a-3);
}

/* The disclosure carries a real border rather than transparent-until-hover: this control is
   the entire entry point to the thing it opens, and one that only announces itself under the
   pointer is not discoverable. Drawn as the same object as the reset beside it. */
.alt-app .okr-grid-show-toggle{
  display:inline-flex; align-items:center; gap:6px;
  height:26px; padding:0 9px;
  background:transparent; border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  font:600 12px/1 var(--a-body); color:var(--a-text); cursor:pointer;
}
.alt-app .okr-grid-show-toggle:hover{ background:var(--a-raised); border-color:var(--a-line-strong); }
.alt-app .okr-grid-show-toggle:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }
.alt-app .okr-grid-show-caret{ font-size:11px; line-height:1; color:var(--a-dim); }

/* WHAT IS ON SCREEN, IN WORDS. Not a control — an inert label beside one — so it takes no
   height floor and no hover, the same distinction CSS/alt/alt-responsive.css already draws
   between a pressable chip and a chip that is only a label. */
.alt-app .okr-grid-show-summary{ font-size:12px; color:var(--a-dim); }

/* THE WAY BACK, AND ONLY WHILE THERE IS SOMETHING TO COME BACK FROM. okrGridShowHtml() emits
   neither this nor the per-axis button unless that axis is actually narrowed — DoD 4f, an
   affordance is absent until it has something to say — so neither ever renders as a control
   that would do nothing. */
.alt-app .okr-grid-show-reset,
.alt-app .okr-grid-show-axis-all{
  height:26px; padding:0 9px;
  background:transparent; border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  font:600 12px/1 var(--a-body); color:var(--a-text); cursor:pointer;
}
.alt-app .okr-grid-show-reset:hover,
.alt-app .okr-grid-show-axis-all:hover{ border-color:var(--a-line-strong); background:var(--a-raised); }
.alt-app .okr-grid-show-reset:focus-visible,
.alt-app .okr-grid-show-axis-all:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }

/* THE PANEL TAKES THE WHOLE ROW under the summary — `flex-basis:100%` rather than a second
   wrapper, since the control row is already the flex container it needs to break out of. */
.alt-app .okr-grid-show-panel{
  flex:0 0 100%; display:flex; flex-direction:column; gap:var(--a-2);
  margin-top:var(--a-1); padding:var(--a-2) var(--a-3);
  background:var(--a-raised); border:1px solid var(--a-line-soft); border-radius:var(--a-r-sm);
}
/* STATED, because the rule above sets `display` and would otherwise beat the UA's own
   `[hidden]{display:none}` — a disclosure that cannot close. */
.alt-app .okr-grid-show-panel[hidden]{ display:none; }

/* THE SCOPE, IN THE PANEL, because the whole risk in two filters on one page is a reader
   assuming this one narrowed the objectives list too. */
.alt-app .okr-grid-show-note{
  margin:0; font-size:11px; line-height:1.5; color:var(--a-faint);
}

.alt-app .okr-grid-show-row{
  display:flex; align-items:center; flex-wrap:wrap; gap:var(--a-2);
}
.alt-app .okr-grid-show-lbl{
  font-size:11px; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  color:var(--a-dim);
  /* The two axis labels line their chips up with each other. Matched to the widest of the two
     words at this size rather than guessed. */
  flex:0 0 62px;
}
.alt-app .okr-grid-show-chips{
  display:flex; align-items:center; flex-wrap:wrap; gap:6px; min-width:0; flex:1 1 auto;
}

/* SHOWN vs HIDDEN, in the card's own vocabulary and not in its filter's. 26px is the suite's
   pressable floor (CSS/alt/alt-responsive.css), which applies here because every one of these
   IS pressable. */
.alt-app .okr-grid-show-chip{
  height:26px; padding:0 10px;
  border:1px dashed var(--a-line); border-radius:var(--a-r-pill);
  background:transparent; color:var(--a-faint);
  font:500 12px/1 var(--a-body); cursor:pointer; white-space:nowrap;
}
.alt-app .okr-grid-show-chip.on{
  border-style:solid; border-color:var(--a-line-strong);
  background:var(--a-panel); color:var(--a-text); font-weight:600;
}
.alt-app .okr-grid-show-chip:hover{ border-color:var(--a-line-strong); color:var(--a-text); }
.alt-app .okr-grid-show-chip:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }

/* THE ONE SENTENCE THE TWO FILTERS CAN NEED BETWEEN THEM: the page filter is narrowed to
   something this grid is not drawing, so the caption's promise of blue has nothing to point at.
   Amber rather than red — it is a state to explain, not a fault to fix. */
.alt-app .okr-grid-show-gap{
  margin:0 0 var(--a-3); padding:var(--a-2) var(--a-3);
  background:var(--a-amber-soft); border:1px solid var(--a-amber); border-radius:var(--a-r-sm);
  font-size:12px; line-height:1.5; color:var(--a-text);
}

/* ---- WHAT THE PERIOD IS KEEPING OFF THE CARD ----
   The page filter can remove whole objectives from this grid rather than just washing them;
   this line is what stops that being silent — see okrGridHiddenByPeriod().
   It is a note, not a warning: nothing is wrong, the reader asked for a period and got it, so
   it takes the quiet raised ground rather than the amber the genuine contradiction note
   carries. Reserving amber for the case that IS a contradiction keeps that one readable. */
.alt-app .okr-grid-outside{
  display:flex; align-items:center; flex-wrap:wrap; gap:var(--a-2);
  margin:0 0 var(--a-3); padding:var(--a-2) var(--a-3);
  background:var(--a-raised); border:1px solid var(--a-line-soft); border-radius:var(--a-r-sm);
  font-size:12px; line-height:1.5; color:var(--a-dim);
}
.alt-app .okr-grid-outside-t{ flex:1 1 220px; min-width:0; }
.alt-app .okr-grid-outside-t b{ color:var(--a-text); font-variant-numeric:tabular-nums; }
/* The same object as the chooser's own resets — one "put it back" control on this card, drawn
   one way. */
.alt-app .okr-grid-outside-btn{
  height:26px; padding:0 9px; flex:0 0 auto;
  background:transparent; border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  font:600 12px/1 var(--a-body); color:var(--a-text); cursor:pointer; white-space:nowrap;
}
.alt-app .okr-grid-outside-btn:hover{ border-color:var(--a-line-strong); background:var(--a-panel); }
.alt-app .okr-grid-outside-btn:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }
