/* ============================================================================
   LORE LAB Steel Test Database - layout, components, responsive
   Mobile-first. Breakpoints per viz-spec 0.9:
     mobile  < 640px   single column, sticky axis, tap-to-expand, 44px targets
     tablet  640-1024px  two columns where earned
     desktop > 1024px  multi-column, hover affordances (additive only)
   ========================================================================= */

/* ---- Generic page heading band ---------------------------------------- */
.pagehead { padding: var(--s-6) 0 var(--s-4); }
.pagehead__eyebrow {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Field Teal reads 3.03:1 on parchment at this size, below the 4.5:1 text
     floor; the DS readme scopes teal to labels/hairlines, not body text. */
  color: var(--ink-muted);
  margin-bottom: var(--s-2);
}
.pagehead h1 { font-size: var(--t-xl); margin-bottom: var(--s-2); }
.pagehead__lead {
  font-size: var(--t-md);
  color: var(--ink-soft);
  max-width: var(--maxw-text);
  margin: 0;
}
@media (min-width: 960px) {
  .pagehead { padding: var(--s-8) 0 var(--s-5); }
  .pagehead h1 { font-size: var(--t-2xl); }
}

/* ---- Breadcrumb -------------------------------------------------------- */
.crumbs {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-4) 0 0;
  font-size: var(--t-sm);
  color: var(--ink-faint);
}
.crumbs a { color: var(--ink-soft); }
.crumbs__sep { color: var(--mist-gray); }

/* ============================================================================
   LANDING / METHODOLOGY
   ========================================================================= */
.hero {
  position: relative;
  padding: var(--s-8) 0 var(--s-6);
  overflow: hidden;
}
.hero__eyebrow {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* Field Teal at 3.03:1 fails the 4.5:1 text floor (gate-checked). */
  color: var(--ink-muted);
  margin-bottom: var(--s-3);
}
.hero h1 {
  font-size: clamp(2.25rem, 7vw, 4rem);
  line-height: 1.02;
  margin-bottom: var(--s-4);
}
.hero__lead {
  font-size: var(--t-md);
  color: var(--ink-soft);
  max-width: 56ch;
}
.hero__cta { margin-top: var(--s-5); display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* The two count stats, as a horizontal almanac-figure strip under the CTA.
   Relocated from the hero's right column to give the edge-geometry diagram the
   full-width room its inset and corner labels need. */
.stats-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
  margin: var(--s-6) 0 0;
  padding-top: var(--s-5);
  border-top: var(--border);
}
.stat { line-height: 1; }
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 6vw, 3rem);
  color: var(--lore-navy);
  display: block;
  margin: 0;
}
.stat__label {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: var(--s-2);
}

/* ---- Edge-geometry diagram band (Milo's SVG) -------------------------- */
/* Full-width band between hero and method: the diagram is the method's anchor.
   The transparent SVG sits on the parchment so the page grain shows through. */
.geo-band {
  padding: 0 0 var(--s-6);
}
.geo {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: var(--s-4);
}
.geo__img {
  display: block;
  width: 100%;
  height: auto;
  /* Cap so the 16:10 vector never balloons on very wide screens; the inset
     stays well above its ~520px legibility floor at this width. */
  max-width: 960px;
}
.geo__cap {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  text-align: center;
  max-width: 60ch;
}
.geo__cap strong { color: var(--lore-olive); font-weight: 700; }

@media (max-width: 679px) {
  /* Deliberate small-screen call: at ~390px the full vector would render near
     360px, below Milo's 520px inset-legibility floor. Rather than crush it,
     constrain the diagram's footprint so it reads as a supporting field-sketch
     and the hero copy stays the priority. The vector stays crisp at any size;
     the main cross-section and its angle labels still teach at this scale. */
  .geo-band { padding-top: var(--s-2); }
  .geo__img { max-width: 320px; }
  .geo__cap { font-size: var(--t-xs); }
}

/* Methodology body sections */
.method { padding: var(--s-7) 0; }
.method__lede { max-width: var(--maxw-text); }

.steps {
  display: grid;
  gap: var(--s-4);
  margin: var(--s-5) 0;
  counter-reset: step;
}
@media (min-width: 680px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step {
  position: relative;
  padding: var(--s-5) var(--s-4) var(--s-4);
  background: var(--parchment-card);
  border: var(--border);
  border-top: 3px solid var(--lore-olive);
  border-radius: var(--radius);
}
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  font-weight: 700;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  display: block;
  margin-bottom: var(--s-2);
}
.step h3 { font-size: var(--t-base); font-family: var(--font-display); margin-bottom: var(--s-2); }
.step p { font-size: var(--t-sm); color: var(--ink-soft); margin: 0; }

/* The headline-metric explainer - the editorial heart, set apart */
.metric-explain {
  margin: var(--s-6) 0;
  padding: var(--s-6);
  background: var(--lore-navy);
  color: var(--parchment);
  border-radius: var(--radius-lg);
  /* Navy surface: the only texture this system allows off-parchment. */
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
}
.metric-explain h2 { color: var(--parchment); font-size: var(--t-lg); }
.metric-explain p { color: rgba(240, 231, 213, 0.86); max-width: 60ch; }
.metric-explain strong { color: #fff; }

/* Two-variable callouts */
.variables { display: grid; gap: var(--s-4); margin-top: var(--s-5); }
@media (min-width: 680px) { .variables { grid-template-columns: repeat(2, 1fr); } }
.variable {
  padding: var(--s-5);
  background: var(--parchment-card);
  border: var(--border);
  border-left: 3px solid var(--field-teal);
  border-radius: var(--radius);
}
.variable h3 { font-size: var(--t-md); margin-bottom: var(--s-2); }
.variable p { font-size: var(--t-sm); color: var(--ink-soft); margin: 0; }

.section-title {
  font-size: var(--t-lg);
  margin-bottom: var(--s-2);
}
.section-intro { color: var(--ink-soft); max-width: var(--maxw-text); margin-bottom: var(--s-5); }

/* ============================================================================
   LANDING INTERACTIVITY FEATURES
   ========================================================================= */

/* --- Feature 2: Spotlight pair (D2 vs MagnaCut contrast card) --- */
.spotlight-band {
  padding: var(--s-6) 0;
  border-top: var(--border);
}
.spotlight-pair {
  display: grid;
  gap: var(--s-4);
}
@media (min-width: 680px) {
  .spotlight-pair { grid-template-columns: 1fr 1fr; }
}
.spotlight-card {
  padding: var(--s-5);
  background: var(--parchment-card);
  border: var(--border);
  border-radius: var(--radius-lg);
  border-top: 3px solid var(--mist-gray);
  cursor: pointer;
  transition: box-shadow var(--dur-ui) var(--ease-out), border-color var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out);
}
.spotlight-card:hover,
.spotlight-card.is-revealed {
  box-shadow: var(--shadow-float);
  transform: translateY(var(--lift-hover));
}
.spotlight-card:active { transform: translateY(1px); box-shadow: var(--shadow-card); }
.spotlight-card--pass { border-top-color: var(--field-teal); }
.spotlight-card--pass:hover,
.spotlight-card--pass.is-revealed { border-top-color: var(--lore-olive); }
.spotlight-card--fail { border-top-color: var(--mist-gray); }
.spotlight-card__label {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s-2);
}
.spotlight-card__name {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  color: var(--lore-navy);
  margin-bottom: var(--s-2);
}
.spotlight-card__stat {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  font-weight: 600;
  margin-bottom: 0;
}
.spotlight-card__reveal {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: var(--border);
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.spotlight-card__reveal p { margin: 0; }

/* --- Feature 4: Near-miss closeness strip --- */
.nearmiss-band {
  padding: var(--s-6) 0;
  border-top: var(--border);
}
.nearmiss-band__head {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  margin-bottom: var(--s-4);
}
.nearmiss-list {
  display: grid;
  gap: var(--s-3);
}
.nearmiss-row {
  display: grid;
  grid-template-columns: 10ch 10ch 1fr 6ch;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--parchment-card);
  border: var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--lore-navy);
  transition: background 100ms ease;
}
.nearmiss-row:hover { background: var(--parchment-deep); text-decoration: none; }
.nearmiss-name { font-weight: 600; font-size: var(--t-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nearmiss-company { font-size: var(--t-xs); color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nearmiss-bar-wrap {
  height: 8px;
  background: var(--parchment-deep);
  border-radius: 999px;
  overflow: hidden;
}
.nearmiss-bar {
  height: 100%;
  background: var(--mist-gray);
  border-radius: 999px;
}
.nearmiss-count {
  font-size: var(--t-xs);
  color: var(--ink-soft);
  text-align: right;
}
@media (max-width: 679px) {
  .nearmiss-row {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
  }
  .nearmiss-name { grid-column: 1; }
  .nearmiss-count { grid-column: 2; text-align: right; }
  .nearmiss-company { grid-column: 1; }
  .nearmiss-bar-wrap { grid-column: 1 / -1; }
}

/* --- Feature 3: Heat-treat spread by brand --- */
.heatsig-band {
  padding: var(--s-6) 0;
  border-top: var(--border);
}
.heatsig-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-3);
}
.heatsig-band__title {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  margin-bottom: 0;
}
.heatsig-desc {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  max-width: 56ch;
  margin-bottom: var(--s-4);
}
.heatsig-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.heatsig-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
  background: var(--parchment-card);
  border: var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.heatsig-table thead th {
  text-align: left;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--parchment-deep);
  padding: var(--s-3);
  border-bottom: 1px solid var(--navy-12);
}
.heatsig-table tbody td {
  padding: var(--s-3);
  border-bottom: 1px solid var(--navy-05);
  vertical-align: middle;
}
.heatsig-table tbody tr:last-child td { border-bottom: 0; }
.heatsig-table .num { font-feature-settings: "tnum" 1; }

/* --- Feature 6: Field testers callout --- */
.testers-band {
  padding: var(--s-5) 0;
  border-top: var(--border);
}
.testers-band__label {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s-3);
}
.testers-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4) var(--s-6);
}
.tester-entry {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
}
.tester-name {
  font-weight: 600;
  font-size: var(--t-base);
  color: var(--lore-navy);
}
.tester-count {
  font-size: var(--t-xs);
  color: var(--ink-faint);
}

/* ============================================================================
   SHARPEN-TO REFERENCE (landing TL;DR)
   Every steel, placed once, at its smallest feasible micro-bevel angle. The
   angle is the visual anchor (large mono degree in an aligned left rail);
   steels read as linked chips grouped under a small category label. No hover,
   no tap: the answer is always on the page.
   ========================================================================= */
.sharpen-ref {
  padding: var(--s-6) 0;
  border-top: var(--border);
}
.sharpen-ref__head { margin-bottom: var(--s-5); }
.sharpen-ref__title { font-size: var(--t-lg); margin-bottom: var(--s-2); }
.sharpen-ref__sub {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  max-width: 60ch;
  margin: 0;
}

.sharpen-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}

/* One angle row. Mobile: angle banner stacks above the chip groups. */
.sharpen-row {
  display: grid;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  background: var(--parchment-card);
  border: var(--border);
  border-left: 3px solid var(--lore-olive);
  border-radius: var(--radius-lg);
}

/* The angle anchor: big mono degree, small unit caption beneath. */
.sharpen-row__angle {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
}
.sharpen-row__deg {
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
  color: var(--lore-olive);
  letter-spacing: -0.01em;
}
/* Render the degree symbol as a glyph after the number without extra markup. */
.sharpen-row__deg::after {
  content: "\00b0";
  font-size: 0.7em;
  vertical-align: super;
}
.sharpen-row__unit {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.sharpen-row__groups {
  display: grid;
  gap: var(--s-4);
}
.sharpen-group__cat {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  margin: 0 0 var(--s-2);
}
.sharpen-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}
/* A steel chip: a link to the detail page, readable, with a comfortable target. */
.sharpen-chip {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 var(--s-3);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--lore-navy);
  background: var(--parchment);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-chip);
  transition: transform var(--dur-ui) var(--ease-out), box-shadow var(--dur-ui) var(--ease-out);
}
/* Chip/tag hover lifts and deepens shadow, never shifts fill colour. */
.sharpen-chip:hover {
  transform: translateY(var(--lift-hover));
  box-shadow: var(--shadow-btn-hover);
  text-decoration: none;
}
.sharpen-chip:active { transform: translateY(1px); box-shadow: var(--shadow-chip); }
/* On touch screens give the landing chips a fuller 40px target. */
@media (max-width: 679px) {
  .sharpen-chip { min-height: 40px; padding: 0 var(--s-4); }
}

/* Tablet and up: angle rail to the left, fixed width so all degrees align in a
   column the eye can scan; chip groups fill the remaining width. */
@media (min-width: 680px) {
  .sharpen-row {
    grid-template-columns: 7.5rem 1fr;
    align-items: start;
    gap: var(--s-5);
  }
  .sharpen-row__angle {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s-1);
    padding-top: var(--s-1);
  }
  .sharpen-row__deg { font-size: var(--t-2xl); }
}

/* Desktop: when an angle holds both categories, lay them side by side. */
@media (min-width: 960px) {
  .sharpen-row__groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-6);
  }
  /* A single-category row keeps its chips on one comfortable measure. */
  .sharpen-row__groups:has(> .sharpen-group:only-child) {
    grid-template-columns: 1fr;
  }
}

/* --- Insights page section headers --- */
.insights-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-3);
}
.insights-section-title {
  font-size: var(--t-lg);
  margin: 0 0 var(--s-4);
}
.insights-section-head .insights-section-title {
  margin-bottom: 0;
}

/* ============================================================================
   INDEX + COMPARE controls
   ========================================================================= */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-3);
  margin: var(--s-4) 0;
}
.control { display: inline-flex; flex-direction: column; gap: 4px; }
.control__label {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  text-transform: uppercase;
}
.field {
  min-height: var(--tap);
  padding: 0 var(--s-3);
  font-family: var(--font-body);
  font-size: var(--t-sm);
  color: var(--lore-navy);
  background: var(--parchment-card);
  border: 1.5px solid var(--navy-12);
  border-radius: var(--radius);
}
.field:focus { border-color: var(--lore-olive); outline: none; }
select.field { cursor: pointer; padding-right: var(--s-5); }

.searchbox { position: relative; flex: 1 1 200px; max-width: 320px; }
.searchbox .field { width: 100%; }

/* Segmented filter toggle */
.segmented { display: inline-flex; border: 1.5px solid var(--navy-12); border-radius: var(--radius-pill); overflow: hidden; }
.segmented button {
  min-height: var(--tap);
  padding: 0 var(--s-3);
  font-size: var(--t-xs);
  font-weight: 600;
  background: var(--parchment-card);
  border: 0;
  color: var(--ink-soft);
  cursor: pointer;
}
.segmented button + button { border-left: 1px solid var(--navy-12); }
.segmented button.is-on { background: var(--lore-olive); color: var(--parchment); }

.result-count { font-size: var(--t-xs); color: var(--ink-faint); margin: var(--s-2) 0 var(--s-4); }

/* The plot lives in a card */
.plot-card { padding: var(--s-4); }
@media (min-width: 960px) { .plot-card { padding: var(--s-5) var(--s-6); } }

/* Mobile: controls collapse behind a single trigger; sheet slides from bottom */
.sheet-trigger { display: none; }
.sheet { display: contents; }

@media (max-width: 679px) {
  /* Plot row recomposes: name line, meta line, then full-width track (1.6) */
  .prow {
    grid-template-columns: 1fr;
    padding: var(--s-2) 0;
    min-height: auto;
  }
  .prow__label { padding: 0 var(--s-1) var(--s-1); }
  .prow__name { white-space: normal; font-size: var(--t-md); }
  .track { width: 100%; }
  /* Sticky axis stays visible while the list scrolls (1.6 / 3.5) */
  .axis {
    position: sticky;
    top: 60px;            /* under the masthead */
    z-index: 20;
    background: var(--parchment-card);
    padding: var(--s-2) 0 0;
    margin: 0 calc(-1 * var(--s-4));
    padding-left: var(--s-4);
    padding-right: var(--s-4);
    height: 30px;
  }
  /* Controls become a bottom sheet */
  .sheet-trigger {
    display: inline-flex;
    margin-left: auto;
  }
  .sheet {
    display: block;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 80;
    background: var(--parchment);
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    box-shadow: 0 -8px 32px -8px rgba(17,34,80,0.3);
    padding: var(--s-5) var(--s-4) calc(var(--s-6) + env(safe-area-inset-bottom));
    transform: translateY(100%);
    transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .sheet.is-open { transform: translateY(0); }
  .sheet__handle {
    width: 40px; height: 4px;
    background: var(--mist-gray);
    border-radius: 999px;
    margin: 0 auto var(--s-4);
  }
  .controls { flex-direction: column; align-items: stretch; }
  .control, .searchbox, .segmented { width: 100%; max-width: none; }
  .segmented { display: flex; }
  .segmented button { flex: 1; }
  .sheet-backdrop {
    position: fixed; inset: 0; z-index: 79;
    background: rgba(17,34,80,0.32);
    opacity: 0; pointer-events: none;
    transition: opacity 220ms ease;
  }
  .sheet-backdrop.is-open { opacity: 1; pointer-events: auto; }
}

/* ============================================================================
   STEEL DETAIL layout
   ========================================================================= */
.detail-top { display: grid; gap: var(--s-5); margin: var(--s-4) 0 var(--s-6); }

.headline-block { padding: var(--s-6); }
.headline-block__angle {
  font-family: var(--font-display);
  font-size: var(--t-mega);
  line-height: 0.92;
  color: var(--lore-navy);
  letter-spacing: -0.01em;
}
.headline-block__deg { font-size: 0.4em; vertical-align: super; color: var(--ink-soft); }
.headline-block__caption { font-size: var(--t-md); color: var(--ink-soft); max-width: 46ch; margin-top: var(--s-3); }
.headline-block__confidence {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: var(--border);
  font-size: var(--t-base);
}
.headline-block__confidence strong { color: var(--lore-navy); }
.caveat {
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  background: var(--mist-gray);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  color: var(--lore-navy);
}
.headline-block--nopass .headline-block__angle { font-size: var(--t-xl); color: var(--ink-faint); }

/* Winning-test block: Field Teal accent = "the proof behind the headline" (2.3) */
.winblock {
  padding: var(--s-5);
  border-left: 3px solid var(--field-teal);
}
.winblock__title {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  margin-bottom: var(--s-3);
}
.speclist { display: grid; grid-template-columns: auto 1fr; gap: var(--s-2) var(--s-4); margin: 0; font-size: var(--t-sm); }
.speclist dt { color: var(--ink-soft); font-weight: 600; }
.speclist dd { margin: 0; color: var(--lore-navy); font-weight: 500; }
.speclist .not-recorded { color: var(--ink-faint); font-style: italic; font-weight: 400; }

.spread-block { padding: var(--s-5); }
.spread-block__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-3); }
.spread-block h2 { font-size: var(--t-lg); margin: 0; }

@media (min-width: 960px) {
  /* Two-column upper region: synthesis left, proof (scatter) right (2.8) */
  .detail-top { grid-template-columns: minmax(320px, 1fr) 1.2fr; align-items: start; }
  .detail-left { display: grid; gap: var(--s-5); }
}

/* Context note under the scatter (heat-damage / small-n) */
.context-note {
  margin-top: var(--s-4);
  padding: var(--s-4);
  background: var(--parchment-deep);
  border: var(--border);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.context-note h3 { font-size: var(--t-base); margin-bottom: var(--s-2); }

/* ============================================================================
   DATA TABLES (Detail supporting table, admin lists)
   ========================================================================= */
.table-card { overflow: hidden; }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}
table.data thead th {
  text-align: left;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--parchment-deep);
  padding: var(--s-3);
  white-space: nowrap;
  border-bottom: 1px solid var(--navy-12);
}
table.data tbody td {
  padding: var(--s-3);
  border-bottom: 1px solid var(--navy-05);
  vertical-align: middle;
}
table.data tbody tr:hover td { background: var(--olive-06); }
table.data .num { font-feature-settings: "tnum" 1; font-variant-numeric: tabular-nums; }
table.data .not-recorded { color: var(--ink-faint); font-style: italic; }

/* Data-quality flag (admin tests table only). The public palette carries no red
   by design; this is a deliberate internal admin signal Sivali asked for, kept
   soft and low-saturation: a muted brick red that reads "review me" on the warm
   parchment, never alarming. Never color-alone: a "!" marker and a row tooltip
   carry the same meaning for non-color and screen-reader users. */
:root {
  --dq-red: 176, 58, 46;  /* muted brick red, admin-only, never data-bearing */
}
/* Tint flagged rows. Specificity matches the :hover rule above so the tint wins
   by source order; a dedicated flagged-hover rule below keeps it red on hover. */
table.data tbody tr.is-flagged > td {
  background: rgba(var(--dq-red), 0.10);
}
table.data tbody tr.is-flagged > td:first-child {
  box-shadow: inset 3px 0 0 0 rgba(var(--dq-red), 0.55);  /* muted red left edge */
}
table.data tbody tr.is-flagged:hover > td {
  background: rgba(var(--dq-red), 0.16);
}
/* The "!" marker: the non-color signal, in the legend and the leading ID cell. */
.dq-flag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-right: var(--s-2);
  border-radius: 999px;
  background: rgba(var(--dq-red), 0.16);
  color: rgb(var(--dq-red));
  font-size: var(--t-xs);
  font-weight: 700;
  line-height: 1;
  vertical-align: middle;
}
.table-legend {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  flex-wrap: wrap;
  margin: 0 0 var(--s-4);
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.table-legend .dq-flag { margin-right: 0; }

/* Sortable headers: the th holds a full-bleed button so the whole header is a
   44px keyboard-activatable target. The button inherits the uppercase header
   look; a caret marks the active column and its direction. */
table.data--sortable thead th[data-sort-type] { padding: 0; }
.th-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  min-height: var(--tap);
  padding: var(--s-2) var(--s-3);
  background: transparent;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: left;
  cursor: pointer;
}
.th-sort:hover { color: var(--lore-navy); background: var(--navy-05); }
/* Caret: a neutral up/down hint when idle, a solid directional mark when active. */
.th-sort__caret {
  flex: none;
  width: 0;
  height: 0;
  opacity: 0.35;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid currentColor;
}
.is-sorted .th-sort { color: var(--lore-olive); }
.is-sorted .th-sort__caret { opacity: 1; }
.is-sorted-desc .th-sort__caret {
  border-bottom: 0;
  border-top: 5px solid currentColor;
}

/* Quick fill toolbar (Add-a-test form) */
.quickfill {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin: 0 0 var(--s-5);
}
.quickfill__hint { font-size: var(--t-xs); color: var(--ink-faint); }

/* Conditional row tick (pass/fail/heat) on the supporting table (2.5) */
.rowtick { display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; }
.rowtick__bar { width: 3px; height: 16px; border-radius: 2px; flex: none; }
.rowtick--pass .rowtick__bar { background: var(--signal-blue); }
.rowtick--fail .rowtick__bar { background: transparent; border: 1.5px solid var(--lore-navy); width: 6px; }
.rowtick--heat .rowtick__bar { background: transparent; border: 1.5px dashed var(--mist-gray); width: 6px; }
.rowtick__txt { font-size: var(--t-xs); font-weight: 600; }

.chip {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--parchment-deep);
  border: 1px solid var(--navy-12);
  color: var(--ink-soft);
  margin: 1px 2px 1px 0;
}

/* Mobile: the 10-column supporting table becomes stacked cards (2.7) */
.test-cards { display: none; }
@media (max-width: 679px) {
  .table-scroll.is-wide { display: none; }
  .test-cards { display: grid; gap: var(--s-3); }
  .test-card {
    padding: var(--s-3) var(--s-4);
    background: var(--parchment-card);
    border: var(--border);
    border-radius: var(--radius);
  }
  .test-card__top { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-2); }
  .test-card__angle { font-family: var(--font-display); font-size: var(--t-lg); }
  .test-card__cuts { margin-left: auto; font-feature-settings: "tnum" 1; font-weight: 600; }
  .test-card dl { display: grid; grid-template-columns: auto 1fr; gap: 2px var(--s-3); margin: 0; font-size: var(--t-sm); }
  .test-card dt { color: var(--ink-soft); }
}

/* ============================================================================
   COMPARE
   ========================================================================= */
.compare-layout { display: grid; gap: var(--s-5); }
.compare-caption {
  margin-top: var(--s-4);
  padding: var(--s-4);
  background: var(--parchment-deep);
  border: var(--border);
  border-left: 3px solid var(--lore-olive);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.compare-caption strong { color: var(--lore-navy); }
.compare-caption.is-warn { border-left-color: var(--lore-navy); }
.gap-readout { font-weight: 600; color: var(--lore-navy); }

.picker { padding: var(--s-5); }
.picker__title { font-size: var(--t-base); font-family: var(--font-display); margin-bottom: var(--s-3); }
.chips-selected { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-3); min-height: 1px; }
.chip-removable {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 34px;
  padding: 0 var(--s-2) 0 var(--s-3);
  background: var(--lore-olive);
  color: var(--parchment);
  border-radius: var(--radius-pill);
  font-size: var(--t-sm);
  font-weight: 600;
}
.chip-removable button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  border: 0; border-radius: 50%;
  background: rgba(240,231,213,0.18);
  color: var(--parchment);
  font-size: 1rem; line-height: 1; cursor: pointer;
}
.chip-removable button:hover { background: rgba(240,231,213,0.32); }
/* Roomier remove target on touch screens (the smallest control on /compare). */
@media (max-width: 679px) {
  .chip-removable { min-height: 38px; }
  .chip-removable button { width: 30px; height: 30px; }
}

.empty-state {
  padding: var(--s-8) var(--s-5);
  text-align: center;
  color: var(--ink-faint);
}
.empty-state__icon { font-size: 2rem; opacity: 0.5; margin-bottom: var(--s-3); }

/* not_found.html: was three inline style="" attributes, moved to classes here. */
.not-found { margin-top: var(--s-9); }
.not-found__title { font-size: var(--t-lg); }
.not-found__cta { margin-top: var(--s-3); }

@media (min-width: 960px) {
  .compare-layout { grid-template-columns: 280px 1fr; align-items: start; }
}

/* Picker option list (typeahead dropdown) */
.combo { position: relative; }
.combo__input { width: 100%; }
.combo__list {
  position: absolute;
  z-index: 40;
  left: 0; right: 0;
  margin-top: 4px;
  max-height: 280px;
  overflow-y: auto;
  background: var(--parchment-card);
  border: 1.5px solid var(--navy-12);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
  list-style: none;
  padding: 4px;
}
.combo__list[hidden] { display: none; }
.combo__opt {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  padding: 0 var(--s-3);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--t-sm);
}
.combo__opt:hover, .combo__opt.is-active { background: var(--olive-06); }
.combo__opt[aria-disabled="true"] { color: var(--ink-faint); cursor: not-allowed; }
.combo__opt[aria-disabled="true"]:hover { background: transparent; }
.combo__opt small { color: var(--ink-faint); font-style: italic; }
.combo__opt--create { border-top: 1px solid rgba(17,34,80,0.12); color: var(--lore-olive); font-style: italic; }

/* ============================================================================
   ADMIN - clean, fast, usable. Not flashy.
   ========================================================================= */
.admin { padding-bottom: var(--s-8); }
.admin-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-5) 0 var(--s-4);
}
.admin-bar h1 { font-size: var(--t-xl); margin: 0; }
.admin-bar__actions { margin-left: auto; display: flex; gap: var(--s-2); flex-wrap: wrap; }
.admin-bar__meta { width: 100%; font-size: var(--t-sm); color: var(--ink-faint); }
.admin-section-hdr { margin: var(--s-5) 0 var(--s-3); }
.admin-section-hdr h2 { font-size: var(--t-base); font-weight: 700; margin: 0; }

.admin-tabs { display: flex; gap: var(--s-1); border-bottom: var(--border); margin-bottom: var(--s-5); }
.admin-tabs a {
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.admin-tabs a:hover { color: var(--lore-navy); text-decoration: none; }
.admin-tabs a.is-active { color: var(--lore-navy); border-bottom-color: var(--lore-olive); }

/* Below 640px the five admin tabs (~374px) overrun the narrowest phones.
   Let the tab row scroll horizontally instead of overflowing the page; keep
   each tab on one line so the active underline stays intact. Tighter padding. */
@media (max-width: 679px) {
  .admin-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }
  .admin-tabs::-webkit-scrollbar { display: none; }
  .admin-tabs a { padding: var(--s-2) var(--s-3); white-space: nowrap; flex: 0 0 auto; }
}

/* Login */
.login-wrap { max-width: 400px; margin: var(--s-9) auto; }
.login-card { padding: var(--s-6); }
.login-card__head { text-align: center; margin-bottom: var(--s-5); }
.login-card__mark { width: 56px; height: 56px; border-radius: 50%; margin-bottom: var(--s-3); }
.login-card h1 { font-size: var(--t-lg); margin: 0; }
.login-card__foot { text-align: center; font-size: var(--t-sm); color: var(--ink-soft); margin-top: var(--s-4); }

/* Admin form */
.form-grid { display: grid; gap: var(--s-4); }
@media (min-width: 680px) { .form-grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 680px) { .form-grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 680px) { .form-grid--4 { grid-template-columns: repeat(4, 1fr); } }
.fieldset {
  border: var(--border);
  border-radius: var(--radius-lg);
  background: var(--parchment-card);
  padding: var(--s-5);
  margin-bottom: var(--s-5);
}
.fieldset__legend {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* Field Teal at this size measures below 4.5:1 on parchment (redesign audit B); ink-muted (darkened, 4.65:1) carries the label instead. */
  color: var(--ink-muted);
  margin-bottom: var(--s-4);
}
.formfield { display: flex; flex-direction: column; gap: var(--s-2); }
.formfield--span2 { grid-column: span 2; }
.formfield label { font-size: var(--t-sm); font-weight: 600; color: var(--ink-soft); }
.formfield label .req { color: var(--lore-olive); }
.input, .select, .textarea {
  min-height: var(--tap);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-body);
  font-size: var(--t-base);
  color: var(--lore-navy);
  background: var(--parchment);
  border: 1.5px solid var(--navy-12);
  border-radius: var(--radius);
  width: 100%;
}
.textarea { min-height: 72px; line-height: 1.5; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--lore-olive); outline: none; background: #fff; }
.formfield__hint { font-size: var(--t-xs); color: var(--ink-faint); }

.checks { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); }
.check { display: inline-flex; align-items: center; gap: var(--s-2); min-height: 36px; font-size: var(--t-sm); cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--lore-olive); }

.alert {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  margin-bottom: var(--s-4);
}
.alert--error { background: #f3e3da; border: 1px solid #d8b9a8; color: #6b3b22; }
.alert--ok    { background: #e2eddf; border: 1px solid #9fbe95; color: #2d5022; }

.form-actions { display: flex; gap: var(--s-3); margin-top: var(--s-2); }

.inline-form { display: inline; }
.row-actions { display: flex; gap: var(--s-2); justify-content: flex-end; }

/* Admin collapsible (steel rename/merge) */
.collapse-row { display: none; }
.collapse-row.is-open { display: table-row; }
.collapse-panel { background: var(--parchment-deep); padding: var(--s-4); }

/* Badge for pass/fail in admin (text-based, not color-only) */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--t-xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
}
/* C9: pass/fail badges use --success/--danger on their surface tints with a
   hairline border, same encoding as records.css .res--p/.res--f, not the
   raw --signal-blue this used before the C9 pass applied everywhere. */
.badge--pass { background: var(--surface-success); border: 1px solid var(--border-success); color: var(--success); }
.badge--fail { background: var(--surface-danger); border: 1px solid var(--border-danger); color: var(--danger); }

@media (max-width: 679px) {
  .formfield--span2 { grid-column: auto; }
  .admin-bar__actions { width: 100%; margin-left: 0; }
}

/* ---- Utilities --------------------------------------------------------- */
.muted { color: var(--ink-faint); }
.mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; }
.stack-sm > * + * { margin-top: var(--s-3); }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.nowrap { white-space: nowrap; }

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ============================================================================
   FOOTER: SiteFooter design-system translation (R2, 2026-09-09)
   Sivali: "Footer design is different from thelorelab.com website." Correct -
   the 2026-09-08 footer below was briefed off URLs scraped from thelorelab.com
   instead of the canonical `components/site/SiteFooter.jsx` in the Lore Lab
   Design System (claude.ai project 1bd5f23f), which has held this shape the
   whole time. This is a literal translation of that component into Jinja +
   plain CSS (no build step, web-delivery.md 1.1): every size, gap and colour
   below is transcribed from the JSX, not redesigned. app.css still owns the
   navy surface, grid texture and admin-key sizing (frozen to this leaf); this
   block restructures .footer__inner and adds the brand/social/contact/
   bottom-bar parts SiteFooter defines that this app never had.

   Four tokens the component names do not exist in this app's token set
   (app.css is frozen) and are substituted below with the nearest already-
   shipped equivalent, one-for-one:
     --footer-offset -> var(--s-9)      already .footer's margin-top in app.css
     --ls-footer      -> var(--ls-label) .18em; this app's uppercase micro-label tracking
     --ls-plate       -> var(--ls-label) same reasoning, join/contact labels
     --navy-line      -> --footer-line, defined below (see contrast note)
   Every other value below (46px 24px 38px padding, 320px min-width, 40ch
   tagline measure, 42px/20px social circle+icon, etc.) is copied from the
   component transcription literally, not mapped onto this app's --s-* scale,
   because those are the DS's own literal numbers, not token references.

   BRAND ASSUMPTION - --navy-line has no DS value, so it is defined locally
   as rgba(240, 231, 213, 0.4). This is NOT the app's old footer-divider tint
   (0.14, ~1.46:1 on navy): the SocialCircle rest-state border is a UI
   component boundary and this leaf's accessibility bar requires 3:1 on an
   interactive border. Measured at 0.4 opacity: 3.15:1 on #112250, the exact
   opacity this footer's own admin-key icon already rests at (app.css line
   ~416), so the new circles read as one family with the existing admin key
   rather than introducing a fifth translucency value. Applied to the
   bottom-bar rule too, since the component names one token for both.
   Milo review recommended if a different rest-state weight is wanted.

   BRAND ASSUMPTION - the strapline's literal `color: var(--field-teal)`
   measures 4.12:1 on #112250 at 11.5px bold, which is normal text under the
   14pt/18.66px bold "large text" threshold and therefore needs 4.5:1, not
   3:1. A hand-lightened teal (#78998e, same hue family) measures 4.93:1 on
   the same navy, following the exact precedent already in this file for
   --ink-muted (brand hex darkened for its own contrast failure on
   parchment, app.css line 78-80). Milo review recommended. ------------------ */
:root {
  --footer-line: rgba(240, 231, 213, 0.4);
  --footer-teal-on-navy: #78998e;  /* field-teal, lightened to clear 4.5:1 on navy; see note above */
}

.footer__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 46px 24px 38px;
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  align-items: flex-start;
  justify-content: space-between;
}

/* ---- Brand block, left: mark + wordmark + strapline, tagline beneath ---- */
.footer__brand-col { flex: 1 1 320px; min-width: 0; }
.footer__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.footer__mark { display: block; flex: none; height: 30px; width: auto; }
.footer__wordmark {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-size: 17px;
  line-height: 1;
  letter-spacing: var(--ls-wordmark);
  color: var(--parchment);
}
.footer__strapline {
  font-size: var(--fs-micro);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-label);  /* substitute for --ls-footer, see note above */
  text-transform: uppercase;
  color: var(--footer-teal-on-navy);  /* lightened field-teal, see BRAND ASSUMPTION above */
  position: relative;
  top: 1px;
}
.footer__tagline {
  margin: 0;
  font-size: 15px;
  line-height: var(--lh-body);
  color: var(--mist-gray);
  max-width: 40ch;
  text-wrap: pretty;
}

/* ---- Join + Contact, right ---------------------------------------------- */
.footer__aside { flex: 0 1 auto; }
.footer__label {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--ls-label);  /* substitute for --ls-plate, see note above */
  text-transform: uppercase;
  color: var(--mist-gray);
  margin: 0 0 14px;
}
.footer__socials {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
}
/* 42px circular icon button. Rest-state border is --footer-line (3.15:1 on
   navy, see BRAND ASSUMPTION above); hover/focus border goes --field-teal
   (4.12:1 on navy, clears the 3:1 interactive-border floor on its own -
   the DS hex needs no lightening here because a 1px BORDER is non-text UI,
   held to 3:1, not the 4.5:1 text floor the strapline is held to). The 2px
   lift is written literally per the brief; this app's own --lift-hover names
   a -1px TRANSLATE DISTANCE elsewhere (sharpen-chip, spotlight-card), not a
   duration, so the DS's `transition: var(--lift-hover)` is not portable and
   is replaced with this app's standard interaction-feedback timing
   (dur-ui/ease-out, 120ms - within web-interaction.md 5.1's 100-200ms band).
   Reduced motion: this file's global `prefers-reduced-motion: reduce` rule
   (bottom of this file) zeroes the transition duration everywhere, the same
   mechanism every other hover in this app already relies on, so no separate
   `no-preference` wrapper is added here. */
.social-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* SiteFooter.jsx says 42px. This app's own floor is --tap (44px), and the
     old footer honoured it; the rebuild dropped to the spec's literal and
     went under (code review, 2026-09-09, measured 42x42 at 390/768/1280).
     44 vs 42 is invisible as a ring; 2px is not worth an under-floor target. */
  width: var(--tap);
  height: var(--tap);
  border-radius: 50%;
  border: 1px solid var(--footer-line);
  transition: border-color var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out);
}
.social-circle:hover,
.social-circle:focus-visible {
  border-color: var(--field-teal);
  transform: translateY(-2px);
  text-decoration: none;
}
.footer__contact {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.footer__mailto {
  /* The rebuild deleted `.footer__groups .footer__nav a { min-height: var(--tap) }`
     and nothing replaced it, so this link fell to its 27px line box (code
     review, 2026-09-09). Restore the floor without changing how it reads:
     inline-flex keeps the underline hugging the text. */
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-size: 14px;
  color: var(--parchment);
  text-decoration: none;
  border-bottom: 1px solid var(--footer-line);
  padding-bottom: 2px;
}
.footer__mailto:hover {
  /* app.css's `.footer__inner a:hover { text-decoration: underline }` (frozen,
     not overridden here otherwise) would double up under the border-bottom
     accent line this component uses instead; neutralised explicitly. */
  text-decoration: none;
  border-bottom-color: var(--field-teal);
}

/* ---- Bottom bar: full-width rule, copyright + admin key inside the same
   max-width column. Sibling of .footer__inner (see base.html), not nested
   inside it, so the rule spans the whole navy width. ---------------------- */
.footer__bottom-bar { border-top: 1px solid var(--footer-line); }
.footer__bottom {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 16px 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-meta);
  color: var(--mist-gray);
}
.footer__copyright { font-size: var(--fs-meta); color: var(--mist-gray); }

/* The discreet admin key (web-interaction.md 6.1) moved out of .footer__inner
   into .footer__bottom to match the SiteFooter bottom-bar structure. app.css
   styles it as `.footer__inner a.footer__admin` (frozen, line ~406) - that
   selector requires a .footer__inner ancestor and no longer matches, so its
   sizing/colour/hover rules are restated here verbatim for the new location.
   `.footer__admin svg` in app.css has no such ancestor requirement and still
   applies unchanged. */
.footer__bottom a.footer__admin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  color: rgba(240, 231, 213, 0.4);
  border-radius: 50%;
  transition: color var(--dur-ui) var(--ease-out), background var(--dur-ui) var(--ease-out);
}
.footer__bottom a.footer__admin:hover,
.footer__bottom a.footer__admin:focus-visible {
  color: var(--parchment);
  background: rgba(240, 231, 213, 0.1);
  text-decoration: none;
}

/* Footer-scoped focus ring: the site-wide `:focus-visible` outline
   (app.css, --lore-olive) measures 2.69:1 on this navy background, below
   this leaf's 3:1 focus-indicator floor. Overridden here for every
   focusable control inside the footer - the social circles, the mailto
   link, and the admin key restored above - since app.css is frozen.
   Parchment measures ~12.5:1 on #112250. */
.footer :focus-visible {
  outline-color: var(--parchment);
}
