/* ============================================================================
   GovTheme by Doghouse — showcase.css
   Chrome for the living style-guide: side nav, section scaffolding, token
   displays. Fully responsive (320px up).

   Two languages in one file, and the theme scope is the line between them.
   Outside it — the ground, the card, the sidenav — is showcase chrome, and it
   wears the marketing brand on literals and --hp-* tokens, like every other
   non-themeable surface. Inside it — .gt-main and everything under it — is the
   product on display, and keeps resolving --gt-* so the customiser repaints it.
   Only govtheme.html loads this file, so its brand rules need no .hp- anchor;
   what is shared across pages belongs in css/brand.css instead.
   ========================================================================== */

/* ── Page ground ── */
/* The brand's dotted ground, from the one set of values in css/brand.css §1.
   The rule has to be restated per surface rather than shared, because a bare
   `body` selector cannot live in a sheet the design system also loads; only
   govtheme.html loads this file, so this copy stays off the demo site.
   No --gt-* here on purpose. The customiser's properties are scoped to
   .gt-main (see the data-gt-theme-scope note in govtheme.html), so the ground
   is outside anything it repaints — which is what lets it be a flat brand
   value rather than something derived from --gt-bg that had to survive dark
   mode. It overrides the token `background: var(--gt-bg)` that tokens.css sets
   on <body> for the other pages. */
body {
  background-color: var(--hp-ground);
  background-image: var(--hp-ground-dots);
  background-size: var(--hp-ground-grid);
  background-position: 0 0;
  background-attachment: fixed;
}

.gt-app { min-height: 100vh; }

/* A focused element, or a followed anchor outside the card, lands 24px under
   the sticky masthead, in place of the kit's margin for its own sticky header.
   Anchors inside the card scroll the card alone (scrollInCard() in
   js/govtheme.js). A margin on each element, not
   scroll-padding on html, which would apply to the masthead too: it never
   moves, so focusing in it would scroll the page up. css/brand.css zeroes it
   on the masthead and the dialog. */
* { scroll-margin-top: calc(var(--hp-masthead-h) + 24px); }

/* Segmented control, palette and mini select live in css/marketing-chrome.css —
   they were defined here and again in demo/css/site.css, and preview.html
   loads neither. One copy now, next to the panel that uses them. */

/* ── Body layout ── */
/* The card the showcase is laid out on: brand chrome, so brand values. It sits
   outside the theme scope and holds the sidenav beside the themed column, which
   is why it cannot be the themed surface itself — outside the scope --gt-bg
   only ever resolves to :root's light default, and a dark look would put light
   ink on it. Its column, and the room it keeps for the launcher tab, are
   .gt-app's in css/marketing-chrome.css.
   It is a window onto the page, the same size as the preview's frame: two
   screens under the masthead less the same 20px above and 24px below
   (css/marketing-chrome.css), scrolling inside, so the page beside it reaches
   the footer as late.
   Positioned, so the specimens' visually hidden labels and inputs, which
   have no positioned ancestor of their own, scroll and clip with it instead
   of stretching the page to the content's full length. */
.gt-layout {
  --hp-card-h: calc(2 * (100vh - var(--hp-masthead-h)) - 44px);
  --hp-card-h: calc(2 * (100dvh - var(--hp-masthead-h)) - 44px);
  position: relative; height: var(--hp-card-h); overflow-y: auto;
  max-width: var(--hp-maxw-shell); margin: 20px auto 24px; display: grid;
  grid-template-columns: 232px 1fr; gap: 0; align-items: start;
  background: var(--hp-surface);
  border: 1px solid var(--hp-line);
  border-radius: var(--hp-radius);
  box-shadow: var(--hp-lift);
  padding-block: 32px;
  padding-right: 32px;
}
/* The theme scope, and with it the themed surface that used to sit on <body>
   (see "Page ground"): the components the customiser repaints are framed
   against a stepped-off ground inset in the brand card, so a dark look darkens
   the specimens and not the showcase around them. */
.gt-main {
  padding: var(--gt-space-10) clamp(20px, 4vw, 56px) var(--gt-space-20);
  min-width: 0;
  background: var(--gt-bg);
  border: 1px solid var(--hp-line);
  border-radius: var(--hp-radius);
}
/* Text colour must re-resolve INSIDE the scope. The kit sets
   `body { color: var(--gt-ink) }`, but the customiser writes its tokens onto
   this element, not <html> — so anything that merely inherits colour was
   getting :root's light-mode ink, which in a dark look meant near-black text
   on a near-black panel (~1.1:1: person-card names, the switch label, the
   file drop-zone, swatch names, mega feature, acknowledgement copy). In light
   looks the two values coincide, so this changes nothing there. */
[data-gt-theme-scope] { color: var(--gt-ink); }

/* A section the card scrolled to takes focus where a followed link would have
   left it (scrollInCard() in js/govtheme.js). It is not a control, so it takes
   no ring, which the kit's global :focus-visible would otherwise draw. */
[data-hp-anchor-target]:focus-visible { box-shadow: none; border-radius: 0; }

/* ── Sidenav ──
   The page's own contents list: showcase chrome, outside the theme scope, so
   it wears the brand while the column beside it follows the customiser.
   Family, tracking and ink are stated rather than inherited — <body> carries
   the kit's font and the kit's base sheet hands bare <a> its --gt-link colour,
   both of which would otherwise show through.
   It sticks to the top of the card it scrolls in, and its scroll box is the
   card's height inside its border and 32px padding, or the foot of a long
   contents list would sit out of reach. Below 1040px it runs in flow (see the
   end of this file). */
.gt-sidenav {
  position: sticky; top: 0; align-self: start;
  padding: 32px 16px 32px 24px;
  max-height: calc(var(--hp-card-h) - 66px); overflow-y: auto;
  font-family: var(--hp-font); letter-spacing: var(--hp-track); color: var(--hp-ink);
}
.gt-sidenav__group + .gt-sidenav__group { margin-top: 24px; }
/* Group titles are accordion toggles: the button only flips aria-expanded
   (wired in js/govtheme.js) and everything visual keys off that attribute,
   so what assistive tech is told and what the eye sees cannot drift apart.
   Deliberately larger and heavier than the links beneath (16/900 vs 15/400). */
.gt-sidenav__title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; background: none; border: 0; cursor: pointer; text-align: left;
  font-family: var(--hp-font); font-size: 16px; font-weight: 900; line-height: 1.2;
  letter-spacing: var(--hp-track); color: var(--hp-ink);
  margin-bottom: 4px; padding: 6px 12px; border-radius: var(--hp-radius-sm);
}
.gt-sidenav__title:hover { background: #F3F4F7; }
.gt-sidenav__chev { flex: 0 0 auto; color: var(--hp-ink-soft); transition: transform .18s var(--hp-ease); }
.gt-sidenav__title[aria-expanded="false"] .gt-sidenav__chev { transform: rotate(-90deg); }
.gt-sidenav__title[aria-expanded="false"] + .gt-sidenav__links { display: none; }
@media (prefers-reduced-motion: reduce) {
  .gt-sidenav__chev { transition: none; }
}
.gt-sidenav a {
  display: block; padding: 7px 12px; border-radius: var(--hp-radius-sm); font-size: 15px;
  font-weight: 400; line-height: 1.3; color: var(--hp-ink-soft); text-decoration: none;
  transition: background-color .14s var(--hp-ease), color .14s var(--hp-ease); min-height: 24px;
}
.gt-sidenav a:hover { background: #F3F4F7; color: var(--hp-ink); }
/* The brand's text-weight red on an 8% tint of itself — 5.0:1, so the current
   section still passes AA where the Figma red at 4.07:1 would not. */
.gt-sidenav a.gt-active { background: #FBECED; color: var(--hp-accent-text); font-weight: 700; }
/* The kit's :focus-visible is a box-shadow in --gt-* colours; out here it would
   paint the design system's default blue onto brand chrome. Same 3px ink
   outline css/brand.css §3 gives every other brand control. */
.gt-sidenav a:focus-visible,
.gt-sidenav__title:focus-visible { outline: 3px solid var(--hp-ink); outline-offset: 2px; box-shadow: none; }

/* ── Section scaffold ── */
.gt-section { padding-top: var(--gt-space-12); margin-top: var(--gt-space-12); border-top: var(--gt-border-width) solid var(--gt-border); }
/* No :first-of-type collapse: #intro (a div) neutralises its own top spacing
   inline, and the old rule also matched the first <section> — a different
   element type — which glued the Colour section straight onto the intro. */
/* The kit's chrome lays the head out as a space-between row (eyebrow+title
   left, optional action right). This page has no head actions and stacks
   title / desc as direct children, so flow them as blocks — otherwise the
   title lands flush right. */
.gt-section__head { display: block; margin-bottom: var(--gt-space-8); }
.gt-section__title { font-size: var(--gt-text-3xl); }
/* Capped: the column is wide enough for the specimens, too wide for a line of prose. */
.gt-section__desc { font-size: var(--gt-text-lg); color: var(--gt-ink-2); margin-top: 12px; line-height: var(--gt-leading-normal); max-width: 80ch; }

.gt-sub { font-family: var(--gt-font-head); font-weight: var(--gt-w-bold); font-size: var(--gt-text-xl); letter-spacing: var(--gt-head-tracking); margin: var(--gt-space-10) 0 var(--gt-space-5); }
.gt-sub:first-child { margin-top: 0; }

/* example panel */
.gt-demo { background: var(--gt-surface); border: var(--gt-border-width) solid var(--gt-border); border-radius: var(--gt-radius-card); padding: var(--gt-space-8); }
.gt-demo--pad-lg { padding: var(--gt-space-10); }
/* The site-header example: the component is position:sticky for real pages,
   which inside a demo box would pin it to the viewport as the page scrolls. */
.gt-demo .gt-site-header { position: static; }
/* Scaled-viewport demo: full-width organisms (the hero) render as if on a
   1280px screen, scaled down to fit the demo box. CSS cannot divide the box
   width by 1280 for the scale factor, so showcase-script.twig computes
   --gt-vp-scale (and the box's height, which transform doesn't affect) with a
   ResizeObserver. No-JS fallback: scale 1, clipped at the box edge. The box
   is a page, so it takes the page ground: a banner without an image paints
   no background of its own. */
.gt-demo--viewport { padding: 0; overflow: hidden; background: var(--gt-bg); }
.gt-demo--viewport > [data-gt-viewport] { width: 1280px; transform: scale(var(--gt-vp-scale, 1)); transform-origin: top left; }
/* The listing example's facets + results. Used to be a fixed inline
   240px 1fr, which could not collapse and forced horizontal page scroll below
   ~600px (WCAG 1.4.10 reflow); the sidebar stacks above the results instead. */
#listing-grid { grid-template-columns: 240px 1fr; gap: 32px; }
/* The tabs example scrolls sideways on narrow screens, like the primary-nav
   example, instead of wrapping a tab onto a second row. The box scrolls, not
   the list: a scrolling list would clip the active tab's underline, which
   overlaps the list's bottom border. max-content carries that border under
   every tab. */
#tabs .gt-demo { overflow-x: auto; }
#tabs .gt-tabs__list { flex-wrap: nowrap; width: max-content; min-width: 100%; }
#tabs .gt-tab { white-space: nowrap; }
/* A dark section band's token remap without its ground or padding: shows how a
   component renders inside .gt-band--dark while the specimen sits on the page. */
.gt-demo-band-scope { background: none; }
/* The primary-nav example scrolls sideways on narrow screens, so its box clips
   vertically too: the bottom padding is the room the tallest open panel and its
   shadow need below the bar, the rich panel's 425px (no token is that large)
   plus the shadow. The rich panel holds its desktop width, or below ~970px its
   link column shrinks to nothing beside the fixed feature and the panel grows
   taller. The top and left padding keep the triggers' focus ring in the box. */
#primarynav .gt-demo { overflow-x: auto; padding: var(--gt-space-2) 0 calc(425px + var(--gt-space-12)) var(--gt-space-2); }
#primarynav .gt-mega--rich { max-width: none; }
/* The pop-up search example is pinned open in the flow, so its panel takes its
   results' full height: a scroller there would catch the page's own scroll. */
#search .gt-cmdk__panel { max-height: none; }
#search .gt-cmdk__results { overflow: visible; }

/* ── Foundations displays ── */
.gt-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.gt-swatch { border-radius: var(--gt-radius-card); overflow: hidden; border: var(--gt-border-width) solid var(--gt-border); background: var(--gt-surface); }
.gt-swatch__chip { height: 72px; border-bottom: var(--gt-border-width) solid var(--gt-border); }
.gt-swatch__info { padding: 10px 12px; }
.gt-swatch__name { font-size: var(--gt-text-sm); font-weight: var(--gt-w-semibold); }
.gt-swatch__val { font-family: var(--gt-font-mono); font-size: var(--gt-text-2xs); color: var(--gt-ink-3); margin-top: 2px; }
/* Every card keeps the badge's line, so a card with no pair lines up with its row. */
.gt-swatch__contrast { font-family: var(--gt-font-mono); font-size: var(--gt-text-2xs); margin-top: 4px; min-height: 1lh; display: flex; align-items: center; gap: 5px; }
.gt-cc-pass { color: var(--gt-success); } .gt-cc-fail { color: var(--gt-error); }

.gt-scale-strip { display: flex; border-radius: var(--gt-radius-card); overflow: hidden; border: var(--gt-border-width) solid var(--gt-border); }
.gt-scale-strip > div { flex: 1; height: 56px; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 4px; font-family: var(--gt-font-mono); font-size: 9px; }

.gt-spec-row { display: flex; align-items: center; gap: var(--gt-space-2) var(--gt-space-16); padding: var(--gt-space-4) 0; border-bottom: var(--gt-border-width) solid var(--gt-border); flex-wrap: wrap; }
.gt-spec-row:last-child { border-bottom: none; }
.gt-spec-row__meta { flex: 0 0 130px; font-family: var(--gt-font-mono); font-size: var(--gt-text-2xs); color: var(--gt-ink-3); }
/* Below 420px beside its label the sample takes its own line under it, rather
   than shrinking until a large type size breaks over four lines or spills out
   of the box. Keyed to the row's width, not the viewport's: the sidenav column
   and the customiser drawer narrow it at widths a media query reads as roomy. */
.gt-spec-row__sample { flex: 1 1 420px; min-width: 0; color: var(--gt-ink); }
.gt-spec-row__sample--bar { display: flex; align-items: center; gap: var(--gt-space-4); }
.gt-spec-row__value { font-family: var(--gt-font-mono); font-size: var(--gt-text-2xs); color: var(--gt-ink-3); }

.gt-token-table { width: 100%; border-collapse: collapse; }
.gt-token-table td { padding: 11px 8px; border-bottom: var(--gt-border-width) solid var(--gt-border); font-size: var(--gt-text-sm); vertical-align: middle; }
.gt-token-table td:first-child { font-family: var(--gt-font-mono); font-size: var(--gt-text-xs); color: var(--gt-primary); white-space: nowrap; }
.gt-token-demo { display: inline-block; }

.gt-radius-demo, .gt-elev-demo { height: 84px; border-radius: var(--gt-radius-card); background: var(--gt-surface); display: grid; place-items: center; font-family: var(--gt-font-mono); font-size: var(--gt-text-2xs); color: var(--gt-ink-3); }
.gt-radius-demo { border: var(--gt-border-width) solid var(--gt-border); }
.gt-icon-set { display: flex; flex-wrap: wrap; gap: var(--gt-space-6); color: var(--gt-ink-2); }
.gt-spacing-demo { flex: 0 0 auto; background: var(--gt-primary); height: 18px; border-radius: 3px; }

/* code chip */
.gt-code { font-family: var(--gt-font-mono); font-size: var(--gt-text-xs); background: var(--gt-surface-sunken); padding: 2px 7px; border-radius: 5px; color: var(--gt-ink-2); }

/* footer */
/* govtheme.html takes the shared brand footer, injected by mountFooter() and
   styled in css/brand.css §5. */

/* ─────────────────────────── RESPONSIVE ─────────────────────────── */

/* The sidenav used to be an off-canvas drawer here, opened by a hamburger in
   the top bar. With that bar gone there was nothing left to open it, so below
   the one-column breakpoint it simply runs in flow as a contents list above
   the content — reachable with no control to find. */
@media (max-width: 1040px) {
  /* A block, not a one-column grid: in the card's fixed height a grid can
     shrink a row below its content, and the next row then starts over it.
     No padding: the sidenav and the themed panel carry their own, and run to
     the card's edges. */
  .gt-layout { display: block; padding: 0; }
  /* One column, so the themed panel is the card's full width: the inset and the
     rounded corners it carries beside the sidenav have nothing left to sit in. */
  .gt-main { border-inline: 0; border-radius: 0; }
  /* In flow at the top of the card, scrolling with it: a scroll box of its own
     here would be a third one nested in the card and the page. Its groups
     fold, so closed it is four titles, and it stays as the reader leaves it
     (scrollSpy() in js/govtheme.js). */
  .gt-sidenav {
    position: static; max-height: none; overflow-y: visible;
    padding: 24px 24px 16px;
  }
}
/* The preview's frame sits 12px from the masthead and the footer here. */
@media (max-width: 720px) {
  .gt-layout {
    --hp-card-h: calc(2 * (100vh - var(--hp-masthead-h)) - 24px);
    --hp-card-h: calc(2 * (100dvh - var(--hp-masthead-h)) - 24px);
    margin-block: 12px;
  }
}
@media (max-width: 760px) {
  .gt-sidenav { padding-inline: 16px; }
  .gt-main { padding: var(--gt-space-8) 16px var(--gt-space-16); }
  .gt-section__title { font-size: var(--gt-text-2xl); }
  .gt-section__desc { font-size: var(--gt-text-md); }
  #listing-grid { grid-template-columns: 1fr; }
  .gt-brand__sub { display: none; }
}
