/* components.css (2026-10-12): the shared parts every page uses, loaded after the page styles so a page
   can't quietly restyle them. The cohesion audit counted six section-label styles; there is now one.
   Add a shared part here, and delete the page copies it replaces. */

/* Section label ("kicker"): a bold label, sentence case, never amber. */
.h-kicker, .hub-kicker, .case-kicker, .hub-section-label, .tec-kicker, .sys-kicker, .stage-n {
  display: inline-flex !important; align-items: center; gap: 10px; margin: 0 0 12px; padding: 0;
  font: 800 .95rem/1.3 var(--face) !important; letter-spacing: 0 !important; text-transform: none !important;
  color: var(--ink-soft) !important;
}
/* No block before a label (2026-10-12, Hayden: "the block pieces in the content blocks just look like a mistake";
   "the little emoji things next to summary"). The pieces stay in the logo, menu, game and footer, where they're the brand. */
:is(.h-kicker, .hub-kicker, .case-kicker, .hub-section-label, .tec-kicker, .sys-kicker, .stage-n)::before { content: none; display: none; }
:is(.field, .case-hero, .audit-hero, .sys-hero, .tec-example) :is(.h-kicker, .hub-kicker, .case-kicker, .hub-section-label, .tec-kicker, .sys-kicker, .stage-n) { color: var(--bone-soft) !important; }
/* A stage label keeps its outcome color in the block. */
.stage--j .stage-n::before { background: var(--found); } .stage--s .stage-n::before { background: var(--understood); } .stage--z .stage-n::before { background: var(--chosen); }

/* Quiet link buttons: tool links and jump chips look like the site's quiet button everywhere. */
.gr-tools a, .wr-tools a, .think-jump a, .follow-tabs [role="tab"] {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; border: 0; border-radius: var(--radius);
  background: var(--field-2) !important; color: var(--bone) !important; font: 700 .95rem/1.2 var(--face); text-decoration: none;
  box-shadow: inset 0 0 0 2px #3a3f4b, inset 0 -4px 0 rgba(0, 0, 0, .3) !important;
}
.follow-tabs [role="tab"][aria-selected="true"] { box-shadow: inset 0 0 0 2px var(--bone), inset 0 -4px 0 var(--step) !important; }
:is(.gr-tools a, .wr-tools a, .think-jump a):active { transform: translateY(2px); }
@media (hover: hover) { :is(.gr-tools a, .wr-tools a, .think-jump a, .follow-tabs [role="tab"]):hover { background: #2a2e38 !important; } }

/* Announcement bar (data/banner.json): one line under the header, the Ducks' green, a sprite and two links. */
.site-banner { background: #154733; color: #f3f1ea; border-bottom: 3px solid #fee123; }
.site-banner-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding-block: 6px; }
.site-banner-duck .sprite { width: 28px; height: auto; display: block; }
.site-banner-tag { padding: 3px 7px; background: #fee123; color: #154733; font: 400 .78rem/1.2 "DotGothic16", ui-monospace, monospace; border-radius: 2px; }
.site-banner-text { flex: 1 1 18em; margin: 0; font-size: .92rem; line-height: 1.4; }
.site-banner-cta, .site-banner-more { display: inline-flex; align-items: center; min-height: 44px; color: #fff; font-weight: 800; text-underline-offset: .2em; }
.site-banner-cta { flex: none; white-space: nowrap; padding: 0 14px; background: #fee123; color: #154733 !important; border-radius: var(--radius); text-decoration: none; box-shadow: inset 0 -3px 0 rgba(0,0,0,.2); }
.site-banner-short { display: none; }
@media (max-width: 640px) { .site-banner-row { flex-wrap: nowrap; padding-block: 2px; } .site-banner-long, .site-banner-more { display: none; } .site-banner-short { display: inline; } .site-banner-text { font-size: .88rem; font-weight: 700; min-width: 0; } .site-banner-duck .sprite { width: 22px; } }
@media print { .site-banner { display: none; } }

/* Whole-card links (2026-10-12, Hayden: "boxes aren't clickable"): a card with one main link is clickable
   anywhere, by stretching that link over the card. The text stays selectable and the markup unchanged. */
.psy-list > li, .wr-inventory > li:not(.wr-inventory-note), .hub-group li, .ent-tiles li { position: relative; }
.psy-list-what > a::after, .wr-inventory > li > span > a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
@media (hover: hover) { .psy-list > li:has(a:hover) { background: #f7f8fa; } }

/* Menu (2026-10-12, Hayden: the core pages need to be "easier to find", and NEXT "feels random").
   Each panel opens with its hub as a big first row; the footer gets search and Bella as real buttons. */
.nav-hub-row { grid-column: 1 / -1; display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 2px 12px; padding: 12px 14px; margin-bottom: 4px;
  background: var(--field); border: 2px solid #3a3f4b; border-left-width: 6px; border-left-color: var(--number); border-radius: 4px; color: var(--bone); text-decoration: none; }
.nav-hub-row .nav-piece { grid-row: span 2; grid-template-columns: repeat(4, 7px); grid-template-rows: repeat(2, 7px); }
.nav-hub-row strong { font-size: 1.15rem; font-weight: 850; }
.nav-hub-row span:last-child { color: var(--bone-soft); font-size: .9rem; }
@media (hover: hover) { .nav-hub-row:hover { background: #22262f; } }
.nav-next { font: 800 .85rem/1.2 var(--face) !important; letter-spacing: 0 !important; color: var(--bone-soft); }
.nav-tool { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; background: var(--field); border: 2px solid #3a3f4b; border-radius: 4px; color: var(--bone); font: 700 .9rem/1 var(--face); text-decoration: none; cursor: pointer; }
.nav-tool img { width: 22px; height: 22px; border-radius: 50%; image-rendering: pixelated; }
.nav-tool-key { display: inline-grid; place-items: center; width: 20px; height: 20px; background: #3a3f4b; border-radius: 3px; font-size: .8rem; }
@media (hover: hover) { .nav-tool:hover { background: #22262f; } }
@media (min-width: 900px) { #panel-writing .nav-col:nth-of-type(2) ul { grid-template-columns: 1fr 1fr; column-gap: 16px; } }

/* Lists: only plain, unclassed lists are prose and join the column; a classed list is a layout (card grids,
   rows, steps) and keeps the full width (fixed 2026-10-12 after 23 card grids were squeezed to 740px). */
/* The reading column (Hayden, 2026-10-12: "NEVER hold paragraphs to the left like this"; text that
   "drifts to the corners of the page"). Headings and body text sit in one centered column, at most
   --measure wide, with the text left-aligned inside it. Wide things (card grids, tables, galleries,
   reports, the split heroes) keep the full width. Enforced by the viewport check's "reading-column"
   rule at 1440 and 2560: no paragraph over 820px wide, none pinned left with empty space beside it. */
main :is(.wrap, [class$="-hero"], main > section) > :is(h1, h2, h3, p, blockquote, ul:not([class]), ol:not([class])):not(.x-measure-ok),
main .wrap > :is(.sec-head, .stage-head, .asked-head, .follow-intro, .clear-line),
main :is(.wrap, [class$="-hero"], main > section) > :is(nav[class$="-crumb"]) {
  max-width: var(--measure);
  margin-inline: auto;
}
/* Every paragraph in the content keeps a readable line length, wherever it's nested. */
/* :not(#_measure) lifts this above page rules like ".think-section .reasoning"; no element has that id. */
main :is(p, blockquote, figcaption, dd):not(.x-measure-ok):not(#_measure) { max-width: min(var(--measure), 66ch); }
/* Prose-led blocks then center as a unit, so a capped paragraph isn't left pinned with empty space beside it. */
.cs-beat { max-width: calc(200px + 32px + var(--measure)); margin-inline: auto; }
@media (max-width: 899px) { .cs-beat { max-width: var(--measure); } }
/* Section intros that sat pinned left over wide content (high scores, the progress report takeaway,
   the writing hub's start line): centered with the reading column. */
:is(.hs-lead, .rp-take, .pub-start):not(.x-measure-ok) { margin-inline: auto; }
/* ...and their headings join the same column, so heading and intro share one left edge. */
:is(.hs, .rp) > :is(h2, .rp-title) { max-width: var(--measure); margin-inline: auto; }
:is(.hs-lead, .rp-take):not(.x-measure-ok):not(#_measure) { max-width: var(--measure); padding-right: max(0px, calc(var(--measure) - 66ch)); }
/* Lists of posts and the log's header read as one centered column too. */
:is(.topic-list, .lg-head) { max-width: var(--measure); margin-inline: auto; }
/* A small-print paragraph in the column keeps the column's left edge (so it lines up with the heading)
   but stops its lines at about 66 of its own characters, by padding the right side instead of narrowing. */
main :is(.wrap, [class$="-hero"], main > section) > p:not(.x-measure-ok):not(#_measure) { max-width: var(--measure); padding-right: max(0px, calc(var(--measure) - 66ch)); }
/* Case-study step labels sit level with their heading, not floating mid-section. */
@media (min-width: 900px) { .cs-beat { align-items: start; } .cs-beat-n { padding-top: .45em; } }

/* Route blocks, joined (Hayden, 2026-10-12: the small "See proof" / "Explore" buttons "feel fragmented;
   think about angles and inter-connectedness"). The card and its action are one T-shaped piece: no gap
   between them, the stem colored by what it leads to (amber proof, teal Bella, neutral system), text at
   a readable size, and the whole piece presses down a step on hover. */
.route-block, .h-routes a.route-block, .nav-start a.route-block, .site-footer a.route-block { gap: 0; }
:where(.route-block) { --rb: var(--step); }
.route-block--proof { --rb: var(--number, #f2b544); }
.route-block--bella { --rb: #3fb6a8; }
.route-block--system { --rb: #d7dbe3; }
.route-block .route-block-body { border-top-color: var(--rb); }
.route-block .route-block-body > span:not(.nav-piece) { font-size: .9rem; }
.route-block .route-block-tail { min-height: 34px; padding: 4px 10px; background: var(--rb); font-size: .9rem; }
@media (prefers-reduced-motion: no-preference) { .route-block { transition: transform var(--m-quick, .12s) steps(2, end); } }
@media (hover: hover) { .route-block:hover { transform: translateY(2px); } }
.route-block--game { --rb: #b48ce8; }
/* Four ways in from the hero: two by two on phones and tablets, a row of four when there's room. */
.h-routes { grid-template-columns: 1fr; }
@media (min-width: 600px) { .h-routes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .h-routes { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.rp-highlights { max-width: var(--measure); margin: 12px auto 0; padding: 10px 14px; border-top: 4px solid var(--number, #f2b544); background: rgba(242, 181, 68, .12); border-radius: 0 0 4px 4px; line-height: 1.5; }
/* The banner with art (Hayden, 2026-10-12: "make our pokemon banner way better, you can bring in graphics
   from the quack report repo"): a field with faint yard lines, and the game's own pixel Ducks standing on
   the banner's bottom edge next to Play. The art steps aside on phones. */
.site-banner--art { background: repeating-linear-gradient(90deg, transparent 0 118px, rgba(255,255,255,.07) 118px 120px), linear-gradient(#18512f, #154733); }
.site-banner-art { display: none; width: auto; height: 64px; margin: -8px 0 -6px; image-rendering: pixelated; filter: drop-shadow(0 3px 0 rgba(0,0,0,.25)); }
@media (min-width: 1000px) { .site-banner--art .site-banner-row { padding-block: 8px 0; align-items: flex-end; } .site-banner--art .site-banner-text, .site-banner--art .site-banner-tag, .site-banner--art .site-banner-duck { align-self: center; } .site-banner--art .site-banner-art { display: block; } .site-banner--art .site-banner-cta, .site-banner--art .site-banner-more { align-self: center; } }

/* Critters (macros.njk critter): small, in a section corner, one per page. Tap: a hop, a line, and Bella's fetch. */
.critter-host { position: relative; }
.critter-spot { position: absolute; right: var(--gutter); bottom: 8px; z-index: 3; display: grid; justify-items: end; }
.critter { display: block; width: 52px; min-height: 44px; padding: 2px; border: 0; background: none; cursor: pointer; }
.critter .sprite { display: block; width: 100%; height: auto; image-rendering: pixelated; }
.critter:focus-visible { outline: 3px solid var(--number); outline-offset: 3px; border-radius: 4px; }
.critter-say { position: absolute; right: 0; bottom: 100%; width: max-content; max-width: min(300px, 72vw); margin-bottom: 8px; padding: 8px 11px; background: #ffffe1; color: #1d2027; border: 2px solid #1d2027; border-radius: 8px; box-shadow: 3px 3px 0 rgba(0,0,0,.3); font-size: .92rem; line-height: 1.4; }
.critter-fetch { position: absolute; right: 100%; bottom: 2px; width: 54px; height: 34px; visibility: hidden; pointer-events: none; }
.critter-fetch .cf-f { position: absolute; inset: 0; width: 100%; height: auto; opacity: 0; }
.critter-fetch[data-f="0"] .cf-f:nth-child(1), .critter-fetch[data-f="1"] .cf-f:nth-child(2),
.critter-fetch[data-f="2"] .cf-f:nth-child(3), .critter-fetch[data-f="3"] .cf-f:nth-child(4) { opacity: 1; }
.critter-ball { position: absolute; right: -4px; top: 6px; width: 10px; height: 10px; background: #e0563b; border: 2px solid #1d2027; border-radius: 50%; }
@media (prefers-reduced-motion: no-preference) {
  .critter.is-poked { animation: critter-hop .45s steps(3) 1; }
  @keyframes critter-hop { 40% { transform: translateY(-8px); } }
  .critter-fetch.is-fetching { visibility: visible; animation: cf-run 3.6s ease-out 1 both; }
  .critter-fetch.is-fetching .critter-ball { animation: cf-drop .3s steps(3) 3.6s 1 both; }
  @keyframes cf-run { from { transform: translateX(-55vw); } to { transform: translateX(0); } }
  @keyframes cf-drop { to { transform: translate(14px, 18px); } }
}
@media (max-width: 699px) { .critter-spot { position: relative; right: auto; bottom: auto; margin: 8px var(--gutter) 6px auto; width: max-content; } }
/* Section heads over card grids are centered over the grid (Hayden's first screenshot: a heading and intro
   pinned left over a wide grid). Prose sections keep left-aligned text in the centered column. */
main .wrap:has(> :is(ul, ol)[class]:not(.x-measure-ok), > div:is([class*="grid"], [class*="-list"], [class*="cards"])) > :is(h2, h2 + p):not(.x-measure-ok):not(.stage-head *) { text-align: center; }
/* High scores and the progress report sit over wide grids and charts: their heads center too. */
:is(.hs, .rp) > :is(h2, .rp-title, .hs-lead, .rp-take, .rp-highlights) { text-align: center; }
/* Opening one disclosure never stretches its neighbor (Hayden, 2026-10-12: "i try to open one and the
   other side opens"). Any grid holding an expandable item lets each card keep its own height. */
:is(ul, ol, div, section):has(> * > details, > details) { align-items: start; }
/* A slightly bigger header on desktop (Hayden, 2026-10-12: "the header should be a little bigger"). Phones
   keep theirs, so the first screen's answer doesn't move down. */
@media (min-width: 900px) {
  .site-header .wrap { min-height: 78px; }
  .wm-name { font-size: 1.32rem; }
  .wm-role { font-size: .82rem; }
  .site-nav :is(.nav-link, .nav-toggle) { font-size: 1.04rem; }
}

/* Inside content, no rows of blocks between sections and no pixel icons on dark topic chips (2026-10-12). */
main .clear-line { display: none; }
.post-topic-icon { display: none; }
/* A calmer footer (Hayden, 2026-10-12: "footer is also too crazy"): a slim block edge instead of a skyline,
   one quiet LinkedIn link instead of two big buttons, and the system block gone (its column links there). */
.footer-edge { max-height: 22px; overflow: hidden; }
.footer-edge .sprite { display: block; width: 100%; height: auto; transform: translateY(calc(22px - 100%)); }
.footer-li { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--bone); font-weight: 700; text-decoration: underline; text-underline-offset: .2em; }
.footer-li .li-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; background: #0a66c2; color: #fff; border-radius: 3px; font: 800 .8rem/1 var(--face); text-decoration: none; }
.footer-col a { font-size: 1rem; } .footer-col li { margin: 0; }
/* Phones (Hayden, 2026-10-12: "pokemon banner on mobile looks bad, button is huge"): one slim line. The action becomes
   a yellow text link that keeps a 44px tap height from the row, not a big yellow block. */
@media (max-width: 640px) {
  .site-banner-row { gap: 8px; padding-block: 0; min-height: 44px; }
  .site-banner-duck .sprite { width: 20px; }
  .site-banner-tag { padding: 2px 5px; font-size: .7rem; }
  .site-banner-text { font-size: .84rem; line-height: 1.25; }
  .site-banner-cta { min-height: 44px; padding: 0 2px; background: none; box-shadow: none; color: #fee123 !important; font-size: .88rem; text-decoration: underline; text-decoration-thickness: 2px; }
}

/* One accordion control everywhere (Hayden, 2026-10-12: "the accordian button is broken design wise"): the round
   chevron from the resume, turning on open, instead of filled squares with a plus or a hyphen. */
body :is(.pillar-more, .piece-more, .ask, .ent-more) > summary::after {
  content: ""; flex: none; display: inline-block; width: 30px; height: 30px; margin-left: auto; border-radius: 50%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4.5L12.5 6' fill='none' stroke='%231d2027' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 15px no-repeat;
  border: 1.5px solid rgba(29, 32, 39, .35); color: transparent; font-size: 0;
}
body :is(.pillar-more, .piece-more, .ask, .ent-more)[open] > summary::after { transform: rotate(180deg); }
@media (prefers-reduced-motion: no-preference) { body :is(.pillar-more, .piece-more, .ask, .ent-more) > summary::after { transition: transform var(--m-in, 200ms) var(--ease-out, ease); } }
/* Two-bar progress (the first and latest month on one scale), used on the homepage proof and the resume. */
.grow-bars { display: grid; gap: 4px; margin-top: 8px; width: 100%; }
.gb-row { display: grid; grid-template-columns: 3ch 1fr 5ch; align-items: center; gap: 8px; font-size: .78rem; font-weight: 700; color: inherit; }
.gb-m { opacity: .75; }
.gb-bar { display: block; height: 8px; width: var(--w); min-width: 4px; background: currentColor; opacity: .35; border-radius: 2px; }
.gb-bar--now { background: var(--number, #f2b33d); opacity: 1; }
.gb-n { text-align: right; font-variant-numeric: tabular-nums; }
.cv-results + .cv-hint { margin-top: 16px; }
.h-proof .h-proof-grow .grow-bars { grid-column: 1 / -1; max-width: 420px; }

/* Industries page (draft until Hayden's review): one card per industry, four labeled lines each, phone first. */
.ind-hero { padding-block: var(--section) var(--section-tight); }
.ind-lede { font-size: 1.1rem; line-height: 1.55; }
.ind-list { display: grid; gap: 16px; }
@media (min-width: 900px) { .ind-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ind-card { padding: 18px 20px; background: #fff; border: 2px solid var(--ink, #1d2027); border-radius: 6px; }
.ind-card h2 { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; font-size: 1.3rem; }
.ind-sprite .sprite { width: 30px; height: auto; display: block; }
.ind-card dl { display: grid; gap: 2px; margin: 0; }
.ind-card dt { margin-top: 8px; font-size: .78rem; font-weight: 800; text-transform: none; color: #47505f; }
.ind-card dd { margin: 0; line-height: 1.5; }
.ind-across { padding-block: var(--section-tight) var(--section); }
