/* ============================================================
   site.css — shared chrome for the Flux showcase.
   Loaded by the hub, the 9 category pages, and the roadmap.
   NOT loaded by the 17 surface frames: those are captured at an
   exact 1280x800 and must stay pristine renders of the product
   with no site chrome on them.

   DEVIATION FROM THE SKILL TEMPLATE, ON PURPOSE:
   the stock site.css is written for a dark, cyan-accented site
   and hardcodes rgba(0,210,255,…) in ~20 rules. Flux's showcase
   is light with a violet accent, so those literals are retuned
   here. Every selector, class name and structural contract is
   preserved byte-for-byte — build-search-index.mjs and
   capture-screenshots.mjs parse the same markup as before. Only
   colour, radius and type are Flux's.

   Tokens are declared here (not only per page) because every
   page in this site shares one palette.

   NAMESPACE WARNING: flux-ui.css also declares :root tokens, and
   it loads AFTER this file, so any name used by both silently
   resolves to Flux's value everywhere. That already happened
   once: this file's --muted (text, #6E6E78) collided with the
   product's shadcn --muted (a background, #EBEBEB) and washed
   out every label on the site. This file's tokens are now named
   --paper/--panel/--ink*/--rule*/--violet*/--r-*; the product's
   keep their real shadcn names. Do not add a token here whose
   name appears in flux-ui.css.
   ============================================================ */

/* Inter, self-hosted. Flux loads Inter from the Google Fonts CDN via a raw
   <link> in src/app/layout.tsx. The showcase must render the same typeface to
   be faithful, but its CSP is `font-src 'self'` (no CDNs, by design), so the
   latin subset is vendored here instead. Same font, same weights, no third
   party. v20 ships as a variable font, so one file covers 400-700. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Ground. Paper, not grey: the product's own --background is #F5F5F5, and
     the showcase sits one step lighter so product frames read as objects
     placed on a page rather than as the page itself. */
  --paper: #FBFAF9;
  --panel: #FFFFFF;
  --panel-2: #F5F5F5;

  --ink: #16161A;
  --ink-2: #3F3F46;
  --ink-3: #6E6E78;

  --rule: rgba(22, 22, 26, .10);
  --rule-strong: rgba(22, 22, 26, .20);

  /* THE accent. Flux's real --primary as it actually renders: globals.css
     ships hsl(262 52% 47%), which resolves to #673AB6. (Its own comment, and
     blueprint.md, both say #673AB7 — rounded by one step. The pixels win.)
     One accent, locked, used for every interactive affordance on the site. */
  --violet: #673AB6;
  --violet-deep: #4B2A86;   /* text-on-paper weight, clears AA on --paper */
  --violet-wash: rgba(103, 58, 182, .08);
  --violet-line: rgba(103, 58, 182, .32);

  /* Flux's real --accent as it renders: hsl(174 100% 29%) = #009485. Reserved
     for data and positive status inside reproduced components. Never a chrome
     affordance: two competing accents is how a design system stops meaning
     anything. */
  --teal: #009485;
  --danger: #C62828;

  /* Flux's real radius scale: --radius: 0.5rem, with md/sm derived as
     calc(--radius - 2px) and calc(--radius - 4px) in tailwind.config.ts. */
  --r-lg: 8px;
  --r-md: 6px;
  --r-sm: 4px;

  --sans: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Flux's tailwind declares font-code as plain `monospace`. Matched, not
     upgraded: naming a nicer mono here would make the showcase look better
     than the product. */
  --mono: monospace;
}

/* ── page shell ──────────────────────────────────────────── */
* { box-sizing: border-box; }

body.sc {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 1240px; margin: 0 auto; padding: 0 32px; }

/* ── masthead ────────────────────────────────────────────── */
/* Editorial, flush left, one hairline under it. No logo lockup, no
   centred hero: this is a reference document and the index is the point. */
.mast { border-bottom: 1px solid var(--rule); background: var(--panel); }
.mast-in { max-width: 1240px; margin: 0 auto; padding: 26px 32px 22px; }
.mast .eyebrow {
  font: 500 11px var(--mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 10px;
}
.mast h1 {
  font-size: 40px; font-weight: 700; letter-spacing: -.025em;
  line-height: 1.1; margin: 0 0 10px;
}
.mast .sub { font-size: 16px; color: var(--ink-2); max-width: 62ch; margin: 0; }

.mast .meta {
  display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center;
  margin-top: 16px; font: 500 12px var(--mono); color: var(--ink-3);
}
.mast .meta b { color: var(--ink-2); font-weight: 600; }

/* ── nav ─────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(251, 250, 249, .92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.nav-in {
  max-width: 1240px; margin: 0 auto; padding: 0 32px;
  display: flex; align-items: center; gap: 10px; height: 60px;
}
.nav .brand {
  display: flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 15px; letter-spacing: -.02em;
  color: var(--ink); text-decoration: none; flex: none;
}
.nav .brand svg { width: 17px; height: 17px; color: var(--violet); }
.nav .links { display: flex; align-items: center; gap: 2px; flex: 1; min-width: 0; overflow: hidden; }
.nav .links a {
  font-size: 13px; font-weight: 500; color: var(--ink-3);
  text-decoration: none; padding: 6px 9px; border-radius: var(--r-md);
  white-space: nowrap;
}
.nav .links a:hover { color: var(--ink); background: rgba(22, 22, 26, .04); }
.nav .links a[aria-current="page"] { color: var(--violet-deep); background: var(--violet-wash); }
.nav .site-tools { display: flex; align-items: center; gap: 8px; flex: none; }

/* ── section heads ───────────────────────────────────────── */
.sec { padding: 44px 0 8px; }
.sec-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.sec h2 { font-size: 22px; font-weight: 700; letter-spacing: -.02em; margin: 0; }
.sec .count { font: 500 12px var(--mono); color: var(--ink-3); }
.sec-purpose {
  font-size: 14px; line-height: 1.65; color: var(--ink-2);
  max-width: 74ch; margin: 10px 0 24px;
}
.sec-head + .sec-purpose { margin-top: 10px; }
.sec-purpose b { color: var(--ink); font-weight: 600; }
.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }

.phead { padding: 34px 0 0; }
.phead h1 { font-size: 32px; font-weight: 700; letter-spacing: -.025em; margin: 0 0 10px; }
.phead p { font-size: 15px; color: var(--ink-2); max-width: 74ch; margin: 0; line-height: 1.65; }

/* ── hub: surface cards ──────────────────────────────────── */
/* The thumbnails are live <iframe>s of the real frame pages, CSS-scaled, not
   screenshots. This matters: a screenshot thumbnail is a second copy that
   drifts the moment the page changes, and nobody notices. An iframe cannot
   drift. */
.shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.shotcard {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: var(--r-lg); overflow: hidden;
  transition: border-color .16s ease, transform .16s ease;
}
.shotcard:hover { border-color: var(--violet-line); transform: translateY(-2px); }
.shotcard:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
/* The lead card spans the row and shows the frame larger: the Now page is the
   product's thesis in one screen and earns the space. */
.shotcard.lead { grid-column: span 3; flex-direction: row; align-items: stretch; }

.thumb { position: relative; overflow: hidden; background: var(--panel-2); border-bottom: 1px solid var(--rule); }
.thumb iframe {
  border: 0; width: 1280px; height: 800px;
  transform-origin: 0 0; pointer-events: none; display: block;
}
/* 1280 -> 372 is 0.290625. The heights follow from the same scale so the
   aspect ratio stays exactly 1280x800 and the frames are never distorted. */
.shotcard:not(.lead) .thumb { height: 232px; }
.shotcard:not(.lead) .thumb iframe { transform: scale(.290625); }
.shotcard.lead .thumb { width: 640px; height: 400px; flex: none; border-bottom: 0; border-right: 1px solid var(--rule); }
.shotcard.lead .thumb iframe { transform: scale(.5); }

.cap { display: flex; align-items: flex-start; gap: 10px; padding: 13px 14px; }
.shotcard.lead .cap { flex-direction: column; justify-content: center; padding: 28px; gap: 8px; }
.cap .num { font: 600 11px var(--mono); color: var(--ink-3); flex: none; padding-top: 2px; }
.cap .t { font-weight: 650; font-size: 14px; letter-spacing: -.01em; }
.shotcard.lead .cap .t { font-size: 22px; letter-spacing: -.02em; }
.cap .d { font-size: 12.5px; color: var(--ink-2); line-height: 1.55; margin-top: 3px; }
.shotcard.lead .cap .d { font-size: 14px; max-width: 46ch; }
.cap .arrow { margin-left: auto; color: var(--ink-3); font-size: 13px; flex: none; }
.shotcard:hover .cap .arrow { color: var(--violet); }
.shotcard.lead .cap .arrow { margin-left: 0; }
/* The badge that says a surface is gated. Not decoration: the reader needs to
   know why a link asks for a password before they click it. */
.cap .lock {
  font: 700 9px var(--sans); letter-spacing: .06em; text-transform: uppercase;
  background: var(--panel-2); color: var(--ink-3);
  border: 1px solid var(--rule-strong); border-radius: 999px; padding: 2px 7px;
}

/* ── hub: category cards ─────────────────────────────────── */
.cats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.cat {
  display: flex; flex-direction: column; gap: 4px;
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: var(--r-lg); padding: 18px; text-decoration: none; color: inherit;
  transition: border-color .16s ease, transform .16s ease;
}
.cat:hover { border-color: var(--violet-line); transform: translateY(-2px); }
.cat:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.cat .e { color: var(--violet); margin-bottom: 6px; }
.cat .e svg { width: 20px; height: 20px; }
.cat .t { font-weight: 650; font-size: 15px; letter-spacing: -.01em; }
.cat .d { font-size: 12.5px; color: var(--ink-2); line-height: 1.55; }
.cat .n { font: 500 11px var(--mono); color: var(--ink-3); margin-top: 8px; }

/* ── hub: filter row ─────────────────────────────────────── */
.subnav {
  display: flex; align-items: center; gap: 6px;
  padding: 14px 0; border-bottom: 1px solid var(--rule); margin-bottom: 8px;
}
.subnav a { font-size: 13px; font-weight: 500; color: var(--ink-3); text-decoration: none; padding: 5px 9px; border-radius: var(--r-md); }
.subnav a:hover { color: var(--ink); background: rgba(22, 22, 26, .04); }
.subnav .grow { flex: 1; }
#filter {
  background: var(--panel); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); padding: 7px 11px; min-width: 220px;
  font: 400 12.5px var(--sans); color: var(--ink); outline: none;
}
#filter::placeholder { color: var(--ink-3); }
#filter:focus { border-color: var(--violet); box-shadow: 0 0 0 3px var(--violet-wash); }
/* Shown by the filter script when nothing matches. Without it the grid just
   empties and the page looks broken rather than filtered. */
.nomatch { padding: 26px 2px; color: var(--ink-3); font-size: 13px; display: none; }
.nomatch.on { display: block; }

@media (max-width: 1000px) {
  .shots, .cats { grid-template-columns: repeat(2, 1fr); }
  .shotcard.lead { grid-column: span 2; flex-direction: column; }
  .shotcard.lead .thumb { width: 100%; height: 300px; border-right: 0; border-bottom: 1px solid var(--rule); }
  .shotcard.lead .thumb iframe { transform: scale(.375); }
  .shotcard.lead .cap { padding: 18px; }
}
@media (max-width: 700px) {
  .shots, .cats { grid-template-columns: 1fr; }
  .shotcard.lead { grid-column: span 1; }
  .subnav { flex-wrap: wrap; }
  #filter { min-width: 0; flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .shotcard, .cat { transition: none; }
  .shotcard:hover, .cat:hover { transform: none; }
}

/* ── component library grid ──────────────────────────────── */
/* The markup here is a CONTRACT parsed by build-search-index.mjs and
   capture-screenshots.mjs: .libcard[id], .libcap .t/.d/.src, .variant .vlabel.
   See references/page-anatomy.md. Restyled for Flux, never renamed. */
/* align-items:start is load-bearing, not cosmetic. Grid rows default to
   `stretch`, so a short card grows to match the tallest in its row, and
   capture clips each .libcard by its BOUNDING BOX: the stretched card ships a
   PNG padded with dead white. One card measured 1439px tall for ~350px of
   content before this line. Nothing on screen looks wrong, which is why it
   went unnoticed until someone opened the PNGs. */
.lib { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 16px; align-items: start; }
.lib.wide { grid-template-columns: repeat(auto-fill, minmax(520px, 1fr)); }
.lib.full { grid-template-columns: 1fr; }

.libcard {
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: var(--r-lg); padding: 16px; scroll-margin-top: 80px;
}
.libcap { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
/* Flux is icon-library-native (107 Lucide icons in src/). The card glyph is a
   real Lucide icon, matching the product's own convention. Tabatha's showcase
   uses emoji here because Tabatha ships no icon library: each site follows its
   own product. */
.libcap .e { color: var(--violet); flex: none; margin-top: 1px; }
.libcap .e svg { width: 17px; height: 17px; }
.libcap .t { font-weight: 650; font-size: 14.5px; letter-spacing: -.01em; }
.libcap .d { color: var(--ink-2); font-size: 13px; margin-top: 3px; line-height: 1.55; }
.libcap .src {
  font-family: var(--mono); font-size: 11px; color: var(--ink-3);
  margin-top: 6px; word-break: break-all;
}

.variants { display: flex; flex-direction: column; gap: 12px; }
.variants.two { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.vlabel {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); margin-bottom: 6px; font-weight: 600;
}
/* The stage the reproduced component stands on. --panel-2 is the product's own
   --background (#F5F5F5), so a component sits on the surface it really sits on.
   Every .vbody must ALSO carry class="fx" (see flux-ui.css): that is what
   supplies the app's type and Lucide's icon sizing to the markup inside. */
.vbody {
  background: var(--panel-2); border: 1px solid var(--rule);
  border-radius: var(--r-md); padding: 12px; overflow: hidden;
}
.vbody.tight { padding: 0; }
/* Named for what it is, not what it looks like: the app's --card surface, for
   components that really sit on a card rather than on the page background. */
.vbody.dark-stage { background: var(--panel); }

/* Status honesty: anything not shipped must SAY so, visibly, on the card.
   Never let a planned component sit next to a shipped one looking identical. */
.status {
  display: inline-block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .06em; font-weight: 700;
  padding: 2px 6px; border-radius: var(--r-sm); margin-left: 6px;
  vertical-align: middle; white-space: nowrap;
}
.status.dev      { background: #FEF3C7; color: #92400E; }  /* In development */
.status.mocked   { background: #FEE2E2; color: #991B1B; }  /* Placeholder / not wired */
.status.dead     { background: #E5E7EB; color: #374151; }  /* Dead code, 0 importers */
.status.unused   { background: #E5E7EB; color: #374151; }  /* Shipped but unimported */
.status.norender { background: #EDE9FE; color: #5B21B6; }  /* Renders no UI */
.status.bug      { background: #FEE2E2; color: #991B1B; }  /* Reproduced bug */

/* A note under a card, for reproduced quirks and honest caveats. */
.cardnote {
  font-size: 12px; line-height: 1.55; color: var(--ink-2);
  border-left: 2px solid var(--violet-line); padding: 2px 0 2px 10px; margin-top: 12px;
}
.cardnote b { color: var(--ink); font-weight: 600; }

/* ── header controls ─────────────────────────────────────── */
.searchbtn {
  display: flex; align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); color: var(--ink-3);
  font: 400 12px var(--sans); padding: 6px 10px; cursor: pointer;
  min-width: 190px; text-align: left; transition: border-color .16s ease, color .16s ease;
}
.searchbtn:hover { border-color: var(--violet-line); color: var(--ink); }
.searchbtn .grow { flex: 1; }
.searchbtn kbd {
  font: 600 10px var(--mono); color: var(--ink-3);
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  padding: 1px 5px; background: var(--panel-2);
}

.reqbtn {
  background: transparent; border: 1px solid var(--violet-line);
  border-radius: var(--r-md); color: var(--violet-deep);
  font: 600 12px var(--sans); padding: 6px 12px; cursor: pointer;
  white-space: nowrap; transition: background .16s ease;
}
.reqbtn:hover { background: var(--violet-wash); }
.reqbtn:active { transform: translateY(1px); }

/* ── per-card feedback actions ───────────────────────────── */
/* Absolutely positioned and transparent until hover/focus, so they add ZERO
   layout height. The capture script clips each .libcard by its bounding box,
   so anything that changed a card's height would silently reflow every card
   screenshot. */
.libcard { position: relative; }
.cardfb {
  position: absolute; top: 8px; right: 8px; z-index: 4;
  display: flex; gap: 4px; opacity: 0; transition: opacity .16s ease;
}
.libcard:hover .cardfb,
.libcard:focus-within .cardfb { opacity: 1; }
.cardfb button {
  background: rgba(255, 255, 255, .94); border: 1px solid var(--rule-strong);
  border-radius: var(--r-sm); color: var(--ink-3);
  font: 500 10px var(--sans); padding: 4px 7px; cursor: pointer;
  backdrop-filter: blur(6px); transition: color .14s ease, border-color .14s ease;
}
.cardfb button:hover { color: var(--ink); border-color: var(--violet-line); }
.cardfb button.bug:hover { color: var(--danger); border-color: rgba(198, 40, 40, .45); }
.cardfb button:focus-visible { opacity: 1; outline: 2px solid var(--violet); outline-offset: 1px; }

/* ── overlay shell (shared by search + feedback) ─────────── */
.ovl {
  position: fixed; inset: 0; z-index: 200; display: none;
  background: rgba(22, 22, 26, .42); backdrop-filter: blur(4px);
  padding: 12vh 20px 20px; overflow-y: auto;
}
.ovl.open { display: block; }
.ovl-box {
  max-width: 620px; margin: 0 auto;
  background: var(--panel); border: 1px solid var(--rule-strong);
  border-radius: var(--r-lg); box-shadow: 0 24px 70px rgba(22, 22, 26, .18);
  overflow: hidden;
}

/* ── search ──────────────────────────────────────────────── */
.sx-top { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--rule); }
.sx-top .ic { color: var(--ink-3); font-size: 14px; }
#sx-input {
  flex: 1; background: transparent; border: 0; outline: none;
  color: var(--ink); font: 400 16px var(--sans);
}
#sx-input::placeholder { color: var(--ink-3); }
.sx-esc {
  font: 600 10px var(--mono); color: var(--ink-3);
  border: 1px solid var(--rule); border-radius: var(--r-sm); padding: 2px 6px;
}

.sx-results { max-height: 52vh; overflow-y: auto; padding: 6px; }
.sx-item {
  display: flex; align-items: flex-start; gap: 11px; padding: 9px 10px;
  border-radius: var(--r-md); text-decoration: none; color: inherit; cursor: pointer;
  border: 1px solid transparent;
}
.sx-item[aria-selected="true"] { background: var(--violet-wash); border-color: var(--violet-line); }
.sx-item .e { font-size: 15px; flex: none; line-height: 1.35; color: var(--ink-3); }
.sx-item .e svg { width: 15px; height: 15px; display: block; }
.sx-item .body { min-width: 0; flex: 1; }
.sx-item .t { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sx-item .d {
  font-size: 11.5px; color: var(--ink-3); line-height: 1.5; margin-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sx-item mark { background: rgba(103, 58, 182, .18); color: var(--ink); border-radius: 2px; padding: 0 1px; }
.sx-kind {
  font: 700 8.5px var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--violet-deep); border: 1px solid var(--violet-line);
  border-radius: 999px; padding: 1px 6px; flex: none;
}
/* Type is carried by the label text; the tint is a second, redundant cue. */
.sx-kind.roadmap { color: #8A5A00; border-color: rgba(138, 90, 0, .32); }
.sx-kind.surface { color: #00695C; border-color: rgba(0, 105, 92, .32); }
.sx-foot {
  display: flex; align-items: center; gap: 14px; padding: 9px 16px;
  border-top: 1px solid var(--rule);
  font-size: 11px; color: var(--ink-3);
}
.sx-foot .grow { flex: 1; }
.sx-foot b { font: 600 10px var(--mono); color: var(--ink-2); }
.sx-empty { padding: 26px 16px; text-align: center; color: var(--ink-3); font-size: 13px; }
.sx-empty .sub { font-size: 11.5px; margin-top: 6px; }

/* ── feedback form ───────────────────────────────────────── */
.fb-head { display: flex; align-items: center; gap: 10px; padding: 15px 18px; border-bottom: 1px solid var(--rule); }
.fb-head h3 { font-size: 15px; font-weight: 600; margin: 0; }
.fb-head .x { margin-left: auto; background: none; border: 0; color: var(--ink-3); font-size: 18px; cursor: pointer; line-height: 1; padding: 2px 6px; }
.fb-head .x:hover { color: var(--ink); }
.fb-body { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.fb-row { display: flex; flex-direction: column; gap: 6px; }
.fb-row > label { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.fb-row .hint { font-size: 11px; color: var(--ink-3); }
.fb-row input[type="text"], .fb-row input[type="email"], .fb-row textarea {
  background: var(--panel); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); color: var(--ink);
  font: 400 13px var(--sans); padding: 9px 11px; outline: none; width: 100%;
}
.fb-row textarea { resize: vertical; min-height: 96px; line-height: 1.55; }
.fb-row input:focus, .fb-row textarea:focus { border-color: var(--violet); box-shadow: 0 0 0 3px var(--violet-wash); }
/* Placeholders must clear WCAG AA against --panel. #767680 measured 4.49:1,
   which misses by a hair; --ink-3 (#6E6E78) is 5.04:1. Measured, not eyeballed. */
.fb-row input::placeholder, .fb-row textarea::placeholder { color: var(--ink-3); }

.fb-seg { display: flex; gap: 8px; }
.fb-seg label {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid var(--rule-strong); border-radius: var(--r-md);
  padding: 9px; font-size: 12.5px; font-weight: 600; cursor: pointer;
  color: var(--ink-3); transition: all .14s ease;
}
.fb-seg input { position: absolute; opacity: 0; pointer-events: none; }
.fb-seg label:hover { color: var(--ink); }
.fb-seg input:checked + span { color: inherit; }
.fb-seg label.on-bug { border-color: rgba(198, 40, 40, .5); background: rgba(198, 40, 40, .07); color: var(--danger); }
.fb-seg label.on-feature { border-color: var(--violet-line); background: var(--violet-wash); color: var(--violet-deep); }
.fb-seg input:focus-visible + span { outline: 2px solid var(--violet); outline-offset: 3px; border-radius: 2px; }

.fb-ctx {
  font: 500 11px var(--mono); color: var(--violet-deep);
  background: var(--violet-wash); border: 1px solid var(--violet-line);
  border-radius: var(--r-sm); padding: 6px 9px;
}
.fb-foot {
  display: flex; align-items: center; gap: 10px; padding: 14px 18px;
  border-top: 1px solid var(--rule); background: var(--panel-2);
}
.fb-foot .grow { flex: 1; }
.fb-foot .note { font-size: 11px; color: var(--ink-3); }
.btn {
  border-radius: var(--r-md); font: 600 12.5px var(--sans);
  padding: 9px 16px; cursor: pointer; border: 1px solid var(--rule-strong);
  background: var(--panel); color: var(--ink-2);
}
.btn:hover { color: var(--ink); border-color: var(--violet-line); }
.btn:active { transform: translateY(1px); }
/* White on #673AB6 measures 7.35:1 — clears AA comfortably. */
.btn.primary { background: var(--violet); border-color: var(--violet); color: #FFFFFF; }
.btn.primary:hover { background: var(--violet-deep); border-color: var(--violet-deep); color: #FFFFFF; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

.fb-msg { font-size: 12px; line-height: 1.5; border-radius: var(--r-md); padding: 10px 12px; display: none; }
.fb-msg.show { display: block; }
.fb-msg.err { background: rgba(198, 40, 40, .07); border: 1px solid rgba(198, 40, 40, .3); color: #8E1F1F; }
.fb-msg.ok { background: rgba(0, 150, 136, .08); border: 1px solid rgba(0, 150, 136, .3); color: #00695C; }
.fb-msg a { color: inherit; font-weight: 600; }
.fb-done { padding: 30px 20px; text-align: center; }
.fb-done .e { font-size: 30px; }
.fb-done h4 { font-size: 15px; margin: 10px 0 6px; }
.fb-done p { font-size: 12.5px; color: var(--ink-3); max-width: 44ch; margin: 0 auto; line-height: 1.6; }

/* ── footer ──────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--rule); margin-top: 60px;
  background: var(--panel); padding: 30px 0 44px;
}
.foot .cols { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 32px; }
.foot h4 { font: 600 12px var(--sans); margin: 0 0 10px; color: var(--ink); }
.foot p, .foot li { font-size: 12.5px; color: var(--ink-3); line-height: 1.65; margin: 0; }
.foot ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 5px; }
.foot a { color: var(--violet-deep); text-decoration: none; }
.foot a:hover { text-decoration: underline; }
.foot .stamp {
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--rule);
  font: 500 11px var(--mono); color: var(--ink-3);
  display: flex; gap: 8px 18px; flex-wrap: wrap;
}

@media (max-width: 900px) {
  .foot .cols { grid-template-columns: 1fr; gap: 24px; }
}
@media (max-width: 700px) {
  .wrap, .mast-in, .nav-in { padding-left: 18px; padding-right: 18px; }
  .mast h1 { font-size: 30px; }
  .nav .links { display: none; }
  .nav .site-tools { gap: 6px; }
  .searchbtn { min-width: 0; }
  .searchbtn .lbl, .searchbtn kbd { display: none; }
  .reqbtn { font-size: 11px; padding: 6px 9px; }
  .ovl { padding: 6vh 12px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .cardfb, .searchbtn, .reqbtn, .btn, .fb-seg label { transition: none; }
  .btn:active, .reqbtn:active { transform: none; }
}
