/* =============================================================================
   04 Blueprint · css/base.css
   Shared by every sheet (page). The art direction lives in DESIGN.md; the
   contract for page builders lives in COMPONENTS.md.
   Order: variables, fonts, reset, base, layout, components, sections,
   utilities, animations, view transitions, media queries.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. Variables
   ----------------------------------------------------------------------------- */
:root {
  /* Palette: one medium, the cyanotype print (DESIGN.md 2.1, contrast in 2.2) */
  --paper: #0d2d56;
  --paper-2: #0a2448;
  --paper-3: #12386a;
  --ink: #eaf2ff;
  --ink-2: #b8cbe8;
  --ink-3: #9cb3d6;
  --construction: #4a7cc0;
  --accent: #ff9466;
  --on-accent: #0d2d56;
  --focus: #ffd45c;
  --grid-minor: rgb(160 200 255 / 0.05);
  /* A major line is drawn over a minor line, so this layer is 5.26%: the two
     together give the 10% major line that the contrast table in DESIGN.md 2.2 measures. */
  --grid-major: rgb(160 200 255 / 0.0526);
  --rule: color-mix(in srgb, var(--ink-2) 30%, transparent);
  --shadow: rgb(3 14 30 / 0.45);
  --construction-60: color-mix(in srgb, var(--construction) 60%, transparent);

  /* Type: one family (Saira) in two cuts */
  --font-text: "Saira", "Saira Fallback", "Saira Fallback Roboto", sans-serif;
  --font-display: "Saira", "Saira Fallback Narrow", "Saira Fallback Condensed", "Saira Fallback Bold",
    "Saira Fallback Roboto Bold", sans-serif;
  --font-arabic: "Segoe UI", "Geeza Pro", "Noto Naskh Arabic", "Noto Sans Arabic", Tahoma, sans-serif;
  --fs-display: clamp(2.75rem, 22.5cqi, 9rem); /* only inside a container (the hero copy column) */
  --fs-h1: clamp(3.25rem, 1.2rem + 9vw, 5.5rem); /* below 64rem; the 64rem block sets the desktop scale */
  --fs-h2: clamp(1.875rem, 1.1rem + 3.2vw, 3.75rem);
  --fs-h3: clamp(1.25rem, 1.05rem + 0.8vw, 1.625rem);
  --fs-stat: clamp(2rem, 1.5rem + 2vw, 3.25rem);
  --fs-lede: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --fs-quote: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  --fs-body: 1.0625rem;
  --fs-small: 0.9375rem;
  --fs-btn: 0.875rem;
  --fs-label: 0.75rem;
  --fs-micro: 0.6875rem;
  --measure: 38rem;

  /* Grid (base values; 48rem and 64rem overrides are in the media queries) */
  --page-pad: 1rem;
  --gutter: 1rem;
  --cols: 4;
  --frame-inset: 0.375rem;
  --frame-line: 1px;
  --header-h: 3.25rem;
  --content-max: 80rem;
  /* Breakpoints, for reference only: media queries use the literal rem values */
  --bp-sm: 30rem;
  --bp-md: 48rem;
  --bp-lg: 64rem;
  --bp-xl: 80rem;

  /* Spacing */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;
  --s-10: 8rem;
  --section-pad: clamp(4rem, 2.5rem + 5vw, 8rem);
  --anchor-offset: calc(var(--frame-inset) + var(--header-h) + 1.5rem);

  /* Pens (ISO 128) */
  --pen-1: 1px;
  --pen-2: 2px;

  /* Motion (the same curves are registered in GSAP by js/main.js) */
  --ease-draft: cubic-bezier(0.65, 0, 0.2, 1);
  --ease-settle: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-snap: cubic-bezier(0.3, 1.4, 0.5, 1);
  --ease-scan: cubic-bezier(0.45, 0.05, 0.35, 1);
  /* The "stamp" CustomEase of js/main.js as a CSS curve (overshoot to 1.06, then it settles).
     A browser without linear() uses the default ease. */
  --ease-stamp: linear(0, 0.174 12.6%, 0.553 24.3%, 0.92 36.3%, 1.045 44.2%, 1.06 50%, 1.02 62%, 0.99 72%, 0.998 82%, 1.003 90%, 1);
  --dur-1: 120ms;
  --dur-2: 240ms;
  --dur-3: 420ms;
  --dur-4: 700ms;
  --dur-5: 900ms;

  /* Paper grid layers (body and the index dialog) */
  --sheet-grid:
    linear-gradient(to right, var(--grid-major) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-major) 1px, transparent 1px),
    linear-gradient(to right, var(--grid-minor) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-minor) 1px, transparent 1px);
  --sheet-grid-size: 5rem 5rem, 5rem 5rem, 1rem 1rem, 1rem 1rem;

  /* CAD grips: four 6px focus squares with a 1px paper outline, centred on the corners
     of a box that is inset -4px (see .grips use in components). */
  --grips:
    linear-gradient(var(--focus) 0 0) 1px 1px / 6px 6px no-repeat,
    linear-gradient(var(--focus) 0 0) calc(100% - 1px) 1px / 6px 6px no-repeat,
    linear-gradient(var(--focus) 0 0) 1px calc(100% - 1px) / 6px 6px no-repeat,
    linear-gradient(var(--focus) 0 0) calc(100% - 1px) calc(100% - 1px) / 6px 6px no-repeat,
    linear-gradient(var(--paper) 0 0) 0 0 / 8px 8px no-repeat,
    linear-gradient(var(--paper) 0 0) 100% 0 / 8px 8px no-repeat,
    linear-gradient(var(--paper) 0 0) 0 100% / 8px 8px no-repeat,
    linear-gradient(var(--paper) 0 0) 100% 100% / 8px 8px no-repeat;

  /* Drawing ticks: 10px L marks at the four corners of a panel */
  --ticks:
    linear-gradient(var(--ink-2) 0 0) 0 0 / 10px 2px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 0 0 / 2px 10px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 100% 0 / 10px 2px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 100% 0 / 2px 10px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 0 100% / 10px 2px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 0 100% / 2px 10px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 100% 100% / 10px 2px no-repeat,
    linear-gradient(var(--ink-2) 0 0) 100% 100% / 2px 10px no-repeat;
}

/* -----------------------------------------------------------------------------
   2. Fonts: Saira text (wdth 100, wght 400..700) and display (wdth 62.5, wght 700),
   plus six measured fallback faces so a swap never moves the layout (DESIGN.md 2.3).
   ----------------------------------------------------------------------------- */
@font-face {
  font-family: "Saira";
  src: url("../fonts/saira-text.woff2") format("woff2");
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
}

@font-face {
  font-family: "Saira";
  src: url("../fonts/saira-display.woff2") format("woff2");
  font-weight: 700;
  font-stretch: 62.5%;
  font-display: swap;
}

/* size-adjust = Saira advance width / fallback advance width over site copy;
   metric overrides = Saira typo metrics (1135 / 439 / 0) / size-adjust. */
@font-face {
  font-family: "Saira Fallback";
  src: local("Arial"), local("ArialMT");
  size-adjust: 104.47%;
  ascent-override: 108.64%;
  descent-override: 42.02%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Saira Fallback Roboto";
  src: local("Roboto"), local("Roboto-Regular");
  size-adjust: 104.18%;
  ascent-override: 108.94%;
  descent-override: 42.14%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Saira Fallback Narrow";
  src: local("Arial Narrow Bold"), local("ArialNarrow-Bold");
  font-weight: 700;
  size-adjust: 70.43%;
  ascent-override: 161.16%;
  descent-override: 62.33%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Saira Fallback Condensed";
  src: local("Roboto Condensed Bold"), local("RobotoCondensed-Bold");
  font-weight: 700;
  size-adjust: 70.96%;
  ascent-override: 159.94%;
  descent-override: 61.86%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Saira Fallback Bold";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 700;
  size-adjust: 57.74%;
  ascent-override: 196.55%;
  descent-override: 76.02%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Saira Fallback Roboto Bold";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 700;
  size-adjust: 62.41%;
  ascent-override: 181.86%;
  descent-override: 70.34%;
  line-gap-override: 0%;
}

/* -----------------------------------------------------------------------------
   3. Reset
   ----------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

/* scroll-padding keeps an anchor target and a focused control clear of the sticky header
   (WCAG 2.2 SC 2.4.11), also when Shift+Tab scrolls the page backward. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: var(--anchor-offset);
}

img,
picture,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

ol,
ul {
  padding: 0;
  list-style: none;
}

h1,
h2,
h3,
h4 {
  font-size: inherit;
  font-weight: inherit;
}

table {
  border-collapse: collapse;
}

/* -----------------------------------------------------------------------------
   4. Base
   ----------------------------------------------------------------------------- */
html {
  background: var(--paper);
  color: var(--ink);
  color-scheme: dark;
  font-family: var(--font-text);
  line-height: 1.6;
}

/* The paper grid scrolls with the sheet; the grain and exposure stay fixed (.paper). */
body {
  min-height: 100dvh;
  padding-block: var(--frame-inset);
  background-image: var(--sheet-grid);
  background-size: var(--sheet-grid-size);
  background-position: center 0;
  font-size: var(--fs-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

p {
  max-width: var(--measure);
  text-wrap: pretty;
}

h2,
h3 {
  text-wrap: balance;
}

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--ink-3);
  text-underline-offset: 0.22em;
  transition: text-decoration-color var(--dur-1) linear;
}

a:hover {
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

main:focus {
  outline: none;
}

::selection {
  background: var(--focus);
  color: var(--paper);
}

:lang(ar) {
  font-family: var(--font-arabic);
  font-size: 1.125em;
  line-height: 1.8;
}

/* Lettering styles. Display: the condensed drawing capitals. */
.t-display,
.sec-title,
.page-h1,
.hero-h1,
.dim-value,
.np-value,
.si-name {
  font-family: var(--font-display);
  font-stretch: 62.5%;
  font-weight: 700;
  text-transform: uppercase;
}

/* Label style: 12px caps */
.t-label,
.kicker,
.sec-label,
.dim-text,
.link-arrow,
.si-top-title,
.field-label,
.stamp-caption {
  font-size: var(--fs-label);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Micro style: 11px caps */
.t-micro,
.nav-no,
.spec-tag,
.receipt figcaption,
.report figcaption,
.report-no,
.tb-cell dt,
.tb-field,
.frame-zones-x,
.frame-zones-y,
.frame-tb {
  font-size: var(--fs-micro);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* -----------------------------------------------------------------------------
   5. Layout
   ----------------------------------------------------------------------------- */
.wrap {
  width: min(100% - 2 * var(--page-pad), var(--content-max));
  margin-inline: auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  column-gap: var(--gutter);
}

/* Main content and the footer sit above the crosshair (z 0) */
main,
.title-block {
  position: relative;
  z-index: 1;
  display: block;
}

/* One section-pad between sections: each section pads its top only */
.section {
  padding-top: var(--section-pad);
}

/* -----------------------------------------------------------------------------
   6. Components
   ----------------------------------------------------------------------------- */

/* 6.1 Skip link */
.skip-link {
  position: fixed;
  top: calc(var(--frame-inset) + 0.5rem);
  left: calc(var(--frame-inset) + 0.5rem);
  z-index: 60;
  padding: 0.75rem 1rem;
  background: var(--focus);
  color: var(--paper);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-300%);
}

.skip-link:focus {
  transform: none;
}

/* 6.2 Paper: grain (alpha capped at 3%), dark mottle and vignette. Fixed, under everything. */
.paper {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, transparent 55%, rgb(2 10 24 / 0.35)),
    radial-gradient(50rem 50rem at 85% 90%, rgb(0 0 0 / 0.12), transparent 70%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.03 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* 6.3 Sheet frame: four opaque bands (the border) and an inner border line */
.sheet-frame {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  border: var(--frame-inset) solid var(--paper);
  view-transition-name: sheet-frame;
}

.sheet-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--frame-line) solid var(--ink-2);
}

/* Zones, scale bar and mini title block exist from 64rem (see media queries) */
.frame-zones-x,
.frame-zones-y,
.frame-scale,
.frame-tb {
  display: none;
}

.frame-zones-x span,
.frame-zones-y span {
  position: relative;
  display: grid;
  flex: 1;
  place-items: center;
  color: var(--ink-3);
  transition: color var(--dur-1) linear;
}

.frame-zones-x span.is-lit,
.frame-zones-y span.is-lit {
  color: var(--accent);
}

/* 6-pixel ticks between zones, from the inner border line outward */
.frame-zones-x span + span::before,
.frame-zones-y span + span::before {
  content: "";
  position: absolute;
  background: var(--ink-3);
}

.frame-zones-x span + span::before {
  bottom: 0;
  left: 0;
  width: 1px;
  height: 6px;
}

.frame-zones-y span + span::before {
  top: 0;
  right: 0;
  width: 6px;
  height: 1px;
}

/* Scale bar: ten alternating segments; the accent fill follows the scroll (no JS) */
.frame-scale-fill {
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
}

/* The mini title block is a tab in the bottom band of the frame, under the frame line at the
   right corner. It is outside the drawing area, so it never covers a label or a heading. */
.frame-tb {
  position: absolute;
  right: 0;
  bottom: calc(-1 * var(--frame-inset));
  height: var(--frame-inset);
  align-items: center;
  gap: 0.625rem;
  padding: 0 0.75rem;
  border-inline: 1px solid var(--ink-2);
  background: var(--paper-2);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: opacity var(--dur-3) var(--ease-settle), transform var(--dur-3) var(--ease-settle);
  view-transition-name: sheet-tb;
}

.frame-tb.is-docked {
  opacity: 0;
  transform: translateY(100%);
}

.frame-tb b {
  color: var(--ink);
  font-weight: 400;
}

/* 6.4 Crosshair (SM6), fine pointers only (js/main.js shows it). Two fixed layers: the
   hairlines run under the content (z 0); the pick box and the snap marks sit above the
   content and the header (z 35, under the frame), so a filled button never hides them. */
.crosshair,
.crosshair-marks {
  position: fixed;
  inset: 0;
  display: none;
  pointer-events: none;
  transition: opacity var(--dur-1) linear;
}

.crosshair {
  z-index: 0;
}

.crosshair-marks {
  z-index: 35;
}

.has-crosshair :is(.crosshair, .crosshair-marks) {
  display: block;
}

:is(.crosshair, .crosshair-marks).is-hidden {
  opacity: 0;
}

.ch-h,
.ch-v,
.ch-pick,
.ch-snap {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
}

.ch-h {
  right: 0;
  height: 1px;
  background: var(--construction-60);
}

.ch-v {
  bottom: 0;
  width: 1px;
  background: var(--construction-60);
}

.ch-pick {
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border: 1px solid var(--construction);
  transition: opacity var(--dur-1) linear;
}

/* Centre snap: a 16px ring (cards and circles) */
.ch-snap {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  opacity: 0;
  transition: opacity var(--dur-1) linear;
}

/* Endpoint snap: a 10px square on the corner nearest the pointer (links and buttons) */
.ch-snap.is-end {
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 0;
}

.crosshair-marks.is-snapped .ch-snap {
  opacity: 1;
}

.crosshair-marks.is-snapped .ch-pick {
  opacity: 0;
}

/* 6.5 Sheet scan: the lit sweep line of a sheet change (SM3) */
.sheet-scan {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  display: none;
  height: 2px;
  background: var(--focus);
  box-shadow: 0 0 0.75rem 0.125rem color-mix(in srgb, var(--focus) 50%, transparent);
  pointer-events: none;
}

html.is-scanning .sheet-scan {
  display: block;
  view-transition-name: sheet-scan;
}

/* 6.6 Sprite: symbols only, never painted */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* 6.7 Icons */
.icon {
  flex: none;
  width: 1rem;
  height: 1rem;
}

/* 6.8 Wordmark: a GD&T feature control frame [ position mark | AMR SAKR ] */
.wordmark {
  display: inline-flex;
  flex: none;
  align-items: stretch;
  height: 2.25rem;
  border: 2px solid var(--ink);
  color: var(--ink);
  text-decoration: none;
}

.wm-mark {
  display: grid;
  width: calc(2.25rem - 4px);
  place-items: center;
  border-right: 2px solid var(--ink);
}

.wm-mark svg {
  width: 1.75rem;
  height: 1.75rem;
  overflow: visible;
}

.wm-arms {
  transform-box: view-box;
  transform-origin: center;
  transition: transform var(--dur-2) var(--ease-snap);
}

.wordmark:hover .wm-arms,
.wordmark:focus-visible .wm-arms {
  transform: scale(1.35);
}

.wm-dot {
  fill: var(--accent);
}

.wm-name {
  display: grid;
  place-items: center;
  padding: 0 0.75rem;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

/* 6.9 Header */
.site-header {
  position: sticky;
  top: var(--frame-inset);
  z-index: 30;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
  view-transition-name: sheet-header;
}

/* Without JS the phone nav takes two rows: too tall to stay on screen (sticky again from 64rem) */
html:not(.js) .site-header {
  position: relative;
}

.header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h);
  column-gap: var(--s-5);
}

.primary-nav {
  flex-basis: 100%;
}

.sheet-nav {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--s-5);
}

.nav-link {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  padding-block: 0.75rem;
  color: var(--ink-2);
  font-size: var(--fs-label);
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: color var(--dur-1) linear;
}

.nav-link:hover,
.nav-link[aria-current="page"] {
  color: var(--ink);
}

.nav-no {
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.nav-link[aria-current="page"] .nav-no {
  color: var(--accent);
}

/* Datum: a filled accent triangle on a 2px accent rule along the bottom of the current link */
.nav-datum {
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  background: var(--accent);
  view-transition-name: nav-datum;
}

.nav-datum::before {
  content: "";
  position: absolute;
  bottom: 2px;
  left: 50%;
  width: 0.5rem;
  height: 0.4375rem;
  background: var(--accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  translate: -50% 0;
}

.site-header .header-cta {
  display: none;
}

/* Index button: only with JS (no JS: the nav shows as a second row) */
.index-toggle {
  display: none;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0 0.875rem;
  border: 1px solid var(--rule);
  color: var(--ink);
  font-size: var(--fs-btn);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: border-color var(--dur-1) linear, background-color var(--dur-1) linear;
}

.index-toggle:hover {
  border-color: var(--ink);
  background: var(--paper-3);
}

.index-toggle .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.js .index-toggle {
  display: inline-flex;
}

.js .primary-nav {
  display: none;
}

/* A browser without <dialog>: keep the inline nav, as without JS */
.no-dialog .index-toggle {
  display: none;
}

.no-dialog .primary-nav {
  display: block;
}

/* 6.10 Index dialog (below 64rem): the drawing register */
.sheet-index {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  border: 0;
  background-color: var(--paper-2);
  background-image: var(--sheet-grid);
  background-size: var(--sheet-grid-size);
  color: var(--ink);
  opacity: 0;
  transform: translateY(-0.75rem);
  transition:
    opacity 300ms var(--ease-settle),
    transform 300ms var(--ease-settle),
    overlay 300ms allow-discrete,
    display 300ms allow-discrete;
}

.sheet-index[open] {
  opacity: 1;
  transform: none;
}

@starting-style {
  .sheet-index[open] {
    opacity: 0;
    transform: translateY(-0.75rem);
  }
}

/* Closed at once when the page returns from the history cache (js/main.js) */
.sheet-index.no-anim,
.sheet-index.no-anim .si-list li {
  transition: none;
}

.sheet-index::backdrop {
  background: var(--shadow);
}

html:has(.sheet-index[open]) {
  overflow: hidden;
}

.si-inner {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  min-height: 100%;
  padding-block: calc(var(--frame-inset) + 0.75rem) var(--s-7);
}

.si-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h);
  border-bottom: 1px solid var(--rule);
}

.si-top-title {
  color: var(--ink-3);
}

.si-close {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0 0.75rem;
  margin-right: -0.75rem;
  color: var(--ink);
  font-size: var(--fs-btn);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.si-list {
  border-top: 2px solid var(--ink);
}

.si-list li {
  transform: translateX(-1rem);
  opacity: 0;
  transition:
    transform 300ms var(--ease-settle) calc(var(--i, 0) * 50ms),
    opacity 300ms var(--ease-settle) calc(var(--i, 0) * 50ms);
}

.sheet-index[open] .si-list li {
  transform: none;
  opacity: 1;
}

@starting-style {
  .sheet-index[open] .si-list li {
    transform: translateX(-1rem);
    opacity: 0;
  }
}

.si-link {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  align-content: center;
  min-height: 4.5rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-2);
  text-decoration: none;
}

.si-link:hover,
.si-link[aria-current="page"] {
  color: var(--ink);
}

.si-no {
  grid-row: span 2;
  align-self: center;
  color: var(--ink-3);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

.si-link[aria-current="page"] .si-no {
  color: var(--accent);
}

.si-name {
  font-size: 2.25rem;
  line-height: 1;
}

.si-title {
  color: var(--ink-3);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.si-datum {
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  background: var(--accent);
}

.si-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  margin-top: auto;
}

/* 6.11 Buttons, links and tags */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  min-height: 3rem;
  padding: 0 1.25rem;
  border: 2px solid transparent;
  font-size: var(--fs-btn);
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  transition:
    background-color var(--dur-1) linear,
    border-color var(--dur-1) linear,
    color var(--dur-1) linear;
}

.btn .icon {
  transition: transform var(--dur-2) var(--ease-snap);
}

.btn:hover .icon {
  transform: translateX(0.25rem);
}

.btn:active {
  transform: translateY(1px);
}

.btn[aria-busy="true"] {
  cursor: progress;
  opacity: 0.6;
}

.btn--primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

.btn--primary:hover {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
}

.btn--secondary {
  border-color: var(--ink-2);
  color: var(--ink);
}

.btn--secondary:hover {
  border-color: var(--ink);
  background: var(--paper-3);
}

/* CAD grips on hover and keyboard focus: buttons, panels that hold a link, spec rows, form cells */
.btn::after,
.panel:has(a, button)::after,
.spec-row::after,
.field::after {
  content: "";
  position: absolute;
  inset: -4px;
  z-index: 2;
  background: var(--grips);
  opacity: 0;
  pointer-events: none;
  transform: scale(0.6);
  transition: opacity var(--dur-2) var(--ease-snap), transform var(--dur-2) var(--ease-snap);
}

.btn:focus-visible::after,
.panel:has(:focus-visible)::after,
.field:focus-within::after {
  opacity: 1;
  transform: none;
}

/* Action rows: full-width buttons on phones, inline from 30rem */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

.actions .btn {
  flex: 1 1 100%;
}

.link-arrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink);
  text-decoration: none;
}

/* A 44px tall tap target around the 16px label; the layout does not change */
.link-arrow::before {
  content: "";
  position: absolute;
  inset: -0.875rem 0;
}

.link-arrow:hover {
  color: var(--accent);
}

.link-arrow .icon {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform var(--dur-2) var(--ease-snap);
}

.link-arrow:hover .icon {
  transform: translateX(0.25rem);
}

.link-arrow[target="_blank"]:hover .icon {
  transform: translate(0.125rem, -0.125rem);
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.spec-tag {
  display: inline-block;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--ink-3);
  color: var(--ink-2);
}

/* 6.12 Panel: rule border plus drawing ticks at the corners (reports share the ticks) */
.panel,
.report {
  position: relative;
  border: 1px solid var(--rule);
}

.panel::before,
.report::before {
  content: "";
  position: absolute;
  inset: -1px;
  background: var(--ticks);
  pointer-events: none;
}

/* 6.13 Section head: a 2px ink rule, label, h2, optional lede */
.sec-head {
  margin-bottom: 2.5rem;
}

.sec-head::before {
  content: "";
  display: block;
  height: 2px;
  margin-bottom: var(--s-3);
  background: var(--ink);
  transform-origin: left;
}

.sec-head--bare::before {
  content: none;
}

.sec-label {
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.sec-no {
  color: var(--accent);
}

.sec-title {
  margin-top: var(--s-4);
  font-size: var(--fs-h2);
  letter-spacing: 0.01em;
  line-height: 0.95;
}

/* SplitText line masks: room for Saira's tall ascent and descenders */
.sl-mask {
  padding-block: 0.12em;
  margin-block: -0.12em;
}

.sec-lede {
  margin-top: var(--s-4);
  color: var(--ink-2);
  font-size: var(--fs-lede);
  line-height: 1.45;
}

/* 6.14 Dimension: |<---- value label ---->| with extension lines */
.dim {
  --ext-below: 0.75rem;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.5rem;
  max-width: none;
}

.dim-line {
  position: absolute;
  top: 50%;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--ink-2);
}

/* Filled 3:1 arrowheads, 10 x 3.5 */
.dim-line::before,
.dim-line::after {
  content: "";
  position: absolute;
  top: -1.25px;
  width: 10px;
  height: 3.5px;
  background: var(--ink-2);
}

.dim-line::before {
  left: 0;
  clip-path: polygon(0 50%, 100% 0, 100% 100%);
}

.dim-line::after {
  right: 0;
  clip-path: polygon(100% 50%, 0 0, 0 100%);
}

/* Extension lines: 6px past the dimension line, down toward the object */
.dim::before,
.dim::after {
  content: "";
  position: absolute;
  top: calc(50% - 6px);
  bottom: calc(-1 * var(--ext-below));
  width: 1px;
  background: var(--construction);
}

.dim::before {
  left: 0;
}

.dim::after {
  right: 0;
}

/* Inline-block, not flex: split words must keep the normal word space */
.dim-text {
  position: relative;
  display: inline-block;
  padding-inline: 0.75rem;
  /* the text breaks the line: a paper strip only where the line runs */
  background: linear-gradient(var(--paper), var(--paper)) center / 100% 0.625rem no-repeat;
  color: var(--ink-2);
  white-space: nowrap;
}

.dim-value {
  margin-right: 0.25rem;
  color: var(--ink);
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  line-height: 1;
}

.dim--v {
  flex-direction: column;
  min-width: 2.5rem;
  min-height: 0;
}

.dim--v .dim-line {
  top: 0;
  right: auto;
  bottom: 0;
  left: 50%;
  width: 1px;
  height: auto;
}

.dim--v .dim-line::before,
.dim--v .dim-line::after {
  top: auto;
  left: -1.25px;
  width: 3.5px;
  height: 10px;
}

.dim--v .dim-line::before {
  top: 0;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.dim--v .dim-line::after {
  right: auto;
  bottom: 0;
  clip-path: polygon(50% 100%, 0 0, 100% 0);
}

.dim--v::before,
.dim--v::after {
  top: auto;
  right: calc(-1 * var(--ext-below));
  bottom: auto;
  left: calc(50% - 6px);
  width: auto;
  height: 1px;
}

.dim--v::before {
  top: 0;
}

.dim--v::after {
  bottom: 0;
}

.dim--v .dim-text {
  padding-block: 0.75rem;
  padding-inline: 0;
  background-size: 0.625rem 100%;
  rotate: 180deg;
  writing-mode: vertical-rl;
}

/* 6.15 Stamps (SM5): sprite symbols in accent with a static ink-grain mask */
.stamp {
  width: 4.5rem;
  height: 4.5rem;
  overflow: visible;
  color: var(--accent);
  opacity: 0.92;
  -webkit-mask: url("../assets/ink-grain.png") 0 0 / 10rem 10rem repeat;
  mask: url("../assets/ink-grain.png") 0 0 / 10rem 10rem repeat;
}

.stamp--received {
  color: var(--focus);
}

.stamp-caption {
  color: var(--ink-2);
}

.stamp-caption b {
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
  color: var(--ink);
  font-weight: 700;
}

.icon-star {
  width: 0.875em;
  height: 0.875em;
  color: var(--accent);
}

/* 6.16 Quotes: marks come from CSS, never from the quoted text */
[data-quote]::before {
  content: "\201C";
}

[data-quote]::after {
  content: "\201D";
}

/* Receipt: a small quote on a 2rem accent leader with a 3px dot */
.receipt {
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  column-gap: var(--s-3);
  max-width: 32rem;
}

.receipt::before {
  content: "";
  grid-row: 1;
  height: 3px;
  margin-top: 0.7em;
  background:
    radial-gradient(circle at 1.5px 50%, var(--accent) 1.5px, transparent 1.6px) no-repeat,
    linear-gradient(var(--accent), var(--accent)) 0 50% / 100% 1px no-repeat;
  transform-origin: left;
}

.receipt blockquote {
  grid-column: 2;
  color: var(--ink);
  font-size: var(--fs-small);
  line-height: 1.55;
}

.receipt figcaption {
  grid-column: 2;
  margin-top: var(--s-2);
  color: var(--ink-3);
}

/* Report: an inspection report card (Reviews register, Home inspection) */
.report {
  break-inside: avoid;
}

.report-figure {
  display: grid;
  gap: var(--s-4);
  padding: var(--s-5) var(--s-5) var(--s-6);
}

.report-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2) var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
}

.report-no {
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.report blockquote {
  max-width: var(--measure);
  color: var(--ink);
  font-size: var(--fs-body);
  line-height: 1.6;
}

.report figcaption {
  padding-right: 4rem;
  color: var(--ink-3);
}

.report .stamp {
  position: absolute;
  right: 0.75rem;
  bottom: -0.75rem;
}

.report:nth-child(5n + 1) .stamp {
  rotate: -7deg;
}

.report:nth-child(5n + 2) .stamp {
  rotate: 4deg;
}

.report:nth-child(5n + 3) .stamp {
  rotate: -2deg;
}

.report:nth-child(5n + 4) .stamp {
  rotate: 8deg;
}

.report:nth-child(5n + 5) .stamp {
  rotate: -11deg;
}

/* 6.17 Spec table: ruled rows of item code / name / scope / pictogram */
.spec-table {
  border-bottom: 1px solid var(--rule);
}

.spec-row {
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  column-gap: var(--s-4);
  row-gap: var(--s-2);
  padding: var(--s-5) var(--s-4);
  transition: background-color var(--dur-1) linear, box-shadow var(--dur-1) linear;
}

/* Top rule of each row (it draws on entry, see "Scroll reveals") */
.spec-row > .spec-rule {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--rule);
  transform-origin: left;
}

.spec-code {
  color: var(--accent);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  line-height: 1.9;
  font-variant-numeric: tabular-nums;
}

.spec-name {
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.2;
}

.spec-scope {
  grid-column: 1 / -1;
  color: var(--ink-2);
}

.spec-icon {
  display: none;
  width: 2rem;
  height: 2rem;
  color: var(--ink-2);
}

/* 6.18 Note list: numbered notes, numbers in label style */
.note-list {
  display: grid;
  gap: var(--s-4);
  counter-reset: note;
}

.note-list > li {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  counter-increment: note;
}

.note-list > li::before {
  content: counter(note, decimal-leading-zero);
  padding-top: 0.25em;
  color: var(--accent);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

/* 6.19 Revision cloud: scalloped accent arcs that bulge outward */
.rev-cloud {
  position: relative;
}

.rev-cloud::after {
  content: "";
  position: absolute;
  inset: -6px;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 100%, transparent 4.5px, var(--accent) 4.5px 6px, transparent 6px) top / 12px 6px repeat-x,
    radial-gradient(circle at 50% 0, transparent 4.5px, var(--accent) 4.5px 6px, transparent 6px) bottom / 12px 6px repeat-x,
    radial-gradient(circle at 100% 50%, transparent 4.5px, var(--accent) 4.5px 6px, transparent 6px) left / 6px 12px repeat-y,
    radial-gradient(circle at 0 50%, transparent 4.5px, var(--accent) 4.5px 6px, transparent 6px) right / 6px 12px repeat-y;
}

/* A form cell uses the same ::after for its CAD grips (hidden until focus): an invalid cell
   shows the cloud instead, above the cells next to it. */
.field.rev-cloud {
  z-index: 1;
}

.field.rev-cloud::after {
  opacity: 1;
  transform: none;
  transition: none;
}

/* 6.20 Status lamp: the text states the status; the lamp never carries it alone */
.status-lamp {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  max-width: none;
  color: var(--ink);
  font-size: var(--fs-small);
  line-height: 1.3;
}

.lamp {
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--focus);
  box-shadow:
    inset 0 0 0 1px var(--paper),
    0 0 0.5rem color-mix(in srgb, var(--focus) 60%, transparent);
}

/* 6.21 Profile links (footer, index dialog, contact) */
.profile-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.profile-link {
  display: grid;
  width: 3rem;
  height: 3rem;
  place-items: center;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  transition: color var(--dur-1) linear, border-color var(--dur-1) linear;
}

.profile-link:hover {
  border-color: var(--ink);
  color: var(--ink);
}

.profile-link svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* 6.22 Form controls: one ruled cell per field (Contact) */
.field {
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--s-1);
  padding: var(--s-3) var(--s-4) var(--s-2);
  background: var(--paper-2);
}

.field:focus-within {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.field-label {
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  color: var(--ink-3);
}

.field-input {
  width: 100%;
  min-height: 3rem;
  padding: 0.5rem 0;
  border: 0;
  border-bottom: 1px solid var(--ink-3);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-size: var(--fs-body);
}

/* The cell carries the focus ring (2px focus outline on .field) */
.field-input:focus {
  outline: none;
  border-bottom-color: var(--focus);
}

select.field-input {
  padding-right: 1.75rem;
  appearance: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.5 4h9L6 10z' fill='%239cb3d6'/%3E%3C/svg%3E") right 0.25rem center / 0.75rem no-repeat;
}

select.field-input option {
  background: var(--paper-2);
  color: var(--ink);
}

textarea.field-input {
  display: block;
  min-height: 12rem;
  line-height: 1.6;
  resize: vertical;
}

.field-error {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-1);
  color: var(--accent);
  font-size: var(--fs-small);
}

.field-error[hidden] {
  display: none;
}

/* Honeypot: off screen for people, present for bots */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* 6.23 Footer: the ISO-style title block */
.title-block {
  padding-block: var(--s-8) var(--s-4);
}

.tb-grid {
  display: grid;
  grid-template-areas:
    "id id"
    "project dwg"
    "title rev"
    "drawn sheet"
    "status status"
    "index index"
    "links links"
    "legal legal";
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  border: 2px solid var(--ink);
  background: var(--rule);
}

.tb-cell {
  min-width: 0;
  padding: var(--s-3) var(--s-4);
  background: var(--paper-2);
}

.tb-cell dt,
.tb-field {
  color: var(--ink-3);
}

.tb-cell dd {
  margin-top: var(--s-1);
  color: var(--ink);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
}

.tb-id {
  grid-area: id;
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--s-4);
  padding-block: var(--s-5);
}

.tb-id p {
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: 1.5;
}

.tb-project { grid-area: project; }
.tb-title { grid-area: title; }
.tb-dwg { grid-area: dwg; }
.tb-rev { grid-area: rev; }
.tb-drawn { grid-area: drawn; }
.tb-status { grid-area: status; }
.tb-sheet { grid-area: sheet; }
.tb-index { grid-area: index; }
.tb-links { grid-area: links; }
.tb-legal { grid-area: legal; }

.tb-scale {
  display: none;
}

.tb-index ol {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-1) var(--s-4);
  margin-top: var(--s-2);
}

.tb-index a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  min-height: 2.25rem;
  padding-block: 0.375rem;
  color: var(--ink-2);
  font-size: var(--fs-small);
  text-decoration: none;
}

.tb-index a:hover,
.tb-index a[aria-current="page"] {
  color: var(--ink);
}

.tb-index a[aria-current="page"] .nav-no {
  color: var(--accent);
}

.tb-links .profile-links {
  margin-top: var(--s-2);
}

.tb-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3) var(--s-5);
  color: var(--ink-3);
  font-size: var(--fs-small);
}

.tb-legal p {
  max-width: none;
}

.projection {
  width: 3rem;
  height: 1.5rem;
  color: var(--ink-3);
}

/* Its own up arrow (#i-arrow-up): a rotated 14px arrow head was too small to read */
.back-to-top .icon {
  width: 1rem;
  height: 1rem;
}

.back-to-top:hover .icon {
  transform: translateY(-0.125rem);
}

/* -----------------------------------------------------------------------------
   7. Sections shared by every page
   ----------------------------------------------------------------------------- */

/* Inner-page hero (Work, Reviews, About, Contact): kicker row, h1 with guides, lede */
.page-hero {
  padding-top: var(--s-8);
}

/* A title-block row: the drawing number sits at the right edge of the sheet */
.page-kicker {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  max-width: none;
  gap: var(--s-2) var(--s-5);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
  color: var(--ink-3);
}

.page-kicker span:first-child {
  color: var(--ink-2);
}

/* Display h1s carry lettering guidelines (cap line and baseline of every line box) */
.hero-h1,
.page-h1 {
  position: relative;
  font-kerning: none;
}

.page-h1 {
  --cap: 0.11em;
  --base: 0.798em;
  --lh: 0.9em;
  margin-top: var(--s-6);
  font-size: var(--fs-h1);
  line-height: 0.9;
  overflow-wrap: break-word;
}

/* Guides start at the frame line at every width: the distance from the content edge to the
   frame is max(page-pad, centring margin) minus the frame inset (100vw may count a classic
   scrollbar; the few extra pixels fall under the opaque frame band). */
.h1-guides {
  --guide-left: calc(var(--frame-inset) - max(var(--page-pad), (100vw - var(--content-max)) / 2));
  position: absolute;
  inset: 0 0 0 var(--guide-left);
  z-index: -1;
  background:
    linear-gradient(to bottom, transparent var(--cap), var(--construction) var(--cap) calc(var(--cap) + 1px), transparent calc(var(--cap) + 1px)) 0 0 / 100% var(--lh) repeat-y,
    linear-gradient(to bottom, transparent var(--base), var(--construction) var(--base) calc(var(--base) + 1px), transparent calc(var(--base) + 1px)) 0 0 / 100% var(--lh) repeat-y;
  opacity: 0.55;
  pointer-events: none;
  transform-origin: left;
}

.h1-line {
  display: block;
  overflow-wrap: break-word;
}

/* The pen nib: a small accent diamond that rides the baseline while letters ink */
.h1-nib {
  position: absolute;
  top: 0;
  left: 0;
  width: 0.14em;
  height: 0.14em;
  margin: -0.07em 0 0 -0.07em;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
  rotate: 45deg;
}

.page-lede {
  margin-top: var(--s-6);
  color: var(--ink-2);
  font-size: var(--fs-lede);
  line-height: 1.45;
}

/* Request for proposal band (every page except Contact) */
.rfp-band {
  position: relative;
  z-index: 1;
  margin-top: var(--section-pad);
  border-top: 2px solid var(--ink);
  background: var(--paper-2);
}

.rfp-inner {
  position: relative;
  padding-block: var(--section-pad);
  padding-left: calc(1.5rem + var(--s-5));
}

/* 45-degree hatch strip on the left edge (no text over it) */
.rfp-inner::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1.5rem;
  border-inline: 1px solid var(--rule);
  background: repeating-linear-gradient(45deg, var(--rule) 0 1px, transparent 1px 7px);
}

.rfp-band .sec-head {
  margin-bottom: var(--s-5);
}

.rfp-text {
  color: var(--ink-2);
  font-size: var(--fs-lede);
  line-height: 1.45;
}

.rfp-band .actions {
  column-gap: var(--s-5);
  margin-top: var(--s-6);
}

/* -----------------------------------------------------------------------------
   8. Utilities
   ----------------------------------------------------------------------------- */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.tnum {
  font-variant-numeric: tabular-nums;
}

/* Keeps one phrase on one line (each credential of the proof line) */
.nobr {
  white-space: nowrap;
}

/* Hide-before-animate, part 1: the hero [data-intro] elements, only with motion allowed.
   js/main.js reveals them in the intro. A sheet that arrived by a sheet change is printed
   complete (html.arrived, set by the boot script before the first frame); the boot failsafe
   adds .motion-fallback after 2.5s if js/main.js never ran.
   The headline (h1 and kicker) never waits for a script below 64rem: it is printed with the
   first frame and only the guidelines rule in. From 64rem it is lettered in by the intro, with
   a CSS deadline (see the 64rem block in "Media queries"). */
html.motion-ok [data-intro] {
  opacity: 0;
}

html.motion-ok :is(h1, .kicker, .page-kicker)[data-intro] {
  opacity: 1;
}

@keyframes intro-deadline {
  to {
    opacity: 1;
  }
}

/* The hero lede paints with the first frame (it is the LCP candidate) and settles 0.75rem into
   place. CSS only: no script and no opacity change. Not after a sheet change (html.arrived). */
html.motion-ok:not(.arrived) .page-lede {
  animation: settle-in var(--dur-3) var(--ease-settle) both;
}

@keyframes settle-in {
  from {
    translate: 0 0.75rem;
  }
}

html.motion-ok .h1-guides[data-intro] {
  opacity: 0.55;
  transform: scaleX(0);
}

html.motion-ok .is-ruled .h1-guides[data-intro] {
  transform: none;
  transition: transform var(--dur-3) var(--ease-draft);
}

html:is(.motion-fallback, .arrived) [data-intro] {
  opacity: 1;
  transform: none;
}

html:is(.motion-fallback, .arrived) .h1-guides[data-intro] {
  opacity: 0.55;
  transform: none;
}

/* Hide-before-animate, part 2: scroll reveals (js/main.js, BP.onEnter). A block that is below
   the viewport when the page loads waits with .rv; it gets .is-in when its top passes 88% of
   the viewport. Content on screen at load never gets .rv. Only opacity and the individual
   translate and scale properties move here (GSAP owns transform, so the two never fight),
   plus the stroke offset of a drawn box. --reveal-delay is the stagger that js/main.js sets. */
.sec-head.rv::before {
  transition: scale var(--dur-4) var(--ease-draft);
}

.sec-head.rv :is(.sec-label, .sec-lede) {
  transition:
    opacity var(--dur-3) var(--ease-settle) var(--rise-delay, 0ms),
    translate var(--dur-3) var(--ease-settle) var(--rise-delay, 0ms);
}

.sec-head.rv .sec-label {
  --rise-delay: 150ms;
}

.sec-head.rv .sec-lede {
  --rise-delay: 270ms;
}

.sec-head.rv:not(.is-in)::before {
  scale: 0 1;
}

.sec-head.rv:not(.is-in) :is(.sec-label, .sec-lede) {
  opacity: 0;
  translate: 0 0.75rem;
}

/* The title shows on entry; its lines rise from a line mask (GSAP SplitText, then reverted) */
.sec-head.rv:not(.is-in) .sec-title {
  opacity: 0;
}

/* Spec rows: the top rule draws, then the row content rises (40ms apart inside the row) */
.spec-row.rv > .spec-rule {
  transition: scale var(--dur-3) var(--ease-draft) var(--reveal-delay, 0ms);
}

.spec-row.rv > :not(.spec-rule) {
  transition:
    opacity var(--dur-3) var(--ease-settle) calc(var(--reveal-delay, 0ms) + 200ms + var(--step, 0ms)),
    translate var(--dur-3) var(--ease-settle) calc(var(--reveal-delay, 0ms) + 200ms + var(--step, 0ms));
}

.spec-row.rv > .spec-name {
  --step: 40ms;
}

.spec-row.rv > .spec-scope {
  --step: 80ms;
}

.spec-row.rv > .spec-icon {
  --step: 120ms;
}

.spec-row.rv:not(.is-in) > .spec-rule {
  scale: 0 1;
}

.spec-row.rv:not(.is-in) > :not(.spec-rule) {
  opacity: 0;
  translate: 0 0.75rem;
}

/* Receipts: the accent leader draws */
.receipt.rv::before {
  transition: scale var(--dur-3) var(--ease-draft);
}

.receipt.rv:not(.is-in)::before {
  scale: 0 1;
}

/* [data-reveal] rises; [data-reveal="children"] staggers its direct children 90ms */
[data-reveal]:not([data-reveal="children"]).rv,
[data-reveal="children"].rv > * {
  transition:
    opacity var(--dur-3) var(--ease-settle) var(--reveal-delay, 0ms),
    translate var(--dur-3) var(--ease-settle) var(--reveal-delay, 0ms);
}

[data-reveal]:not([data-reveal="children"]).rv:not(.is-in),
[data-reveal="children"].rv:not(.is-in) > * {
  opacity: 0;
  translate: 0 0.75rem;
}

/* Stamps wait until BP.stamp() lands them (it sets data-stamped) */
:is(.report, .log-row).rv:not([data-stamped]) .stamp,
.stamp.rv:not([data-stamped]) {
  opacity: 0;
}

/* -----------------------------------------------------------------------------
   9. Animations
   ----------------------------------------------------------------------------- */
.status-lamp.is-blinking .lamp {
  animation: lamp-blink 960ms steps(1, end) 1;
}

@keyframes lamp-blink {
  0% { opacity: 1; }
  25% { opacity: 0.25; }
  50% { opacity: 1; }
  75% { opacity: 0.25; }
  100% { opacity: 1; }
}

@keyframes sheet-enter {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes scale-fill {
  to {
    transform: scaleY(1);
  }
}

/* Browsers without cross-document view transitions (Firefox today) */
html.no-vt.motion-ok main {
  animation: sheet-enter 360ms var(--ease-settle) both;
}

/* -----------------------------------------------------------------------------
   10. View transitions: the sheet change (SM3). The old sheet stays still; the
   new sheet prints behind a lit sweep line; the datum and title block cross-fade.
   ----------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

/* Opaque pairs: replace the UA plus-lighter blend, or old + new overexpose the sheet */
::view-transition-old(root),
::view-transition-new(root),
::view-transition-old(sheet-header),
::view-transition-new(sheet-header) {
  mix-blend-mode: normal;
}

::view-transition-old(root),
::view-transition-old(sheet-header),
::view-transition-new(sheet-header) {
  animation: none;
}

::view-transition-new(root) {
  animation: print-down var(--dur-4) var(--ease-scan) both;
}

::view-transition-group(sheet-scan) {
  animation: scan-down var(--dur-4) var(--ease-scan) both;
}

::view-transition-group(nav-datum) {
  animation-duration: 420ms;
  animation-timing-function: var(--ease-snap);
}

::view-transition-group(sheet-tb) {
  animation-duration: 420ms;
}

/* The mini title block fades in sequence (old out, then new in), so two strings of different
   widths never overlap; both images keep their natural size, anchored at the right edge. */
::view-transition-old(sheet-tb),
::view-transition-new(sheet-tb) {
  height: 100%;
  object-fit: none;
  object-position: right center;
}

::view-transition-old(sheet-tb) {
  animation: tb-out 160ms var(--ease-settle) both;
}

::view-transition-new(sheet-tb) {
  animation: tb-in 240ms var(--ease-settle) 160ms both;
}

html:active-view-transition-type(back)::view-transition-new(root) {
  animation-name: print-up;
}

html:active-view-transition-type(back)::view-transition-group(sheet-scan) {
  animation-name: scan-up;
}

@keyframes print-down {
  from { clip-path: inset(0 0 100% 0); }
  to { clip-path: inset(0); }
}

@keyframes print-up {
  from { clip-path: inset(100% 0 0 0); }
  to { clip-path: inset(0); }
}

@keyframes scan-down {
  from { transform: translateY(-2px); }
  to { transform: translateY(100vh); }
}

@keyframes scan-up {
  from { transform: translateY(100vh); }
  to { transform: translateY(-2px); }
}

@keyframes tb-out {
  to { opacity: 0; }
}

@keyframes tb-in {
  from { opacity: 0; }
}

/* -----------------------------------------------------------------------------
   11. Media queries (mobile first)
   ----------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Hover-only effects: never stuck on after a tap */
@media (hover: hover) {
  .btn:hover::after,
  .panel:has(a, button):hover::after,
  .spec-row:hover::after {
    opacity: 1;
    transform: none;
  }

  .spec-row:hover {
    background: var(--paper-3);
    box-shadow: inset 2px 0 0 var(--accent);
  }
}

@media (min-width: 30rem) {
  .actions .btn {
    flex: 0 0 auto;
  }
}

@media (min-width: 48rem) {
  :root {
    --page-pad: 2.5rem;
    --gutter: 1.25rem;
    --cols: 8;
    --frame-inset: 0.75rem;
  }

  .spec-row {
    grid-template-columns: 4.5rem minmax(0, 2fr) minmax(0, 3fr) 2rem;
    align-items: start;
  }

  .spec-scope {
    grid-column: auto;
  }

  .spec-icon {
    display: block;
  }

  /* Tablets: Status takes two cells (its text stays on one line), the profiles stand beside the
     identity cell (two by two), and the sheet index has a full row. Scale shows from 64rem. */
  .tb-grid {
    grid-template-areas:
      "id id id links"
      "project title dwg rev"
      "drawn status status sheet"
      "index index index index"
      "legal legal legal legal";
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .tb-index ol {
    grid-template-columns: repeat(5, auto);
    justify-content: start;
  }
}

@media (min-width: 64rem) {
  :root {
    --page-pad: 4rem;
    --gutter: 1.5rem;
    --cols: 12;
    --frame-inset: 1.25rem;
    --frame-line: 2px;
    --header-h: 3.75rem;
    --fs-h1: clamp(5rem, 0.9rem + 6.4vw, 6.5rem); /* the h1 shares its row with an aside from here */
  }

  /* Frame furniture */
  .frame-zones-x {
    position: absolute;
    top: calc(-1 * var(--frame-inset));
    right: 0;
    left: 0;
    display: flex;
    height: var(--frame-inset);
  }

  .frame-zones-y {
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(-1 * var(--frame-inset));
    display: flex;
    flex-direction: column;
    width: var(--frame-inset);
  }

  .frame-scale {
    position: absolute;
    top: 50%;
    right: calc(-1 * var(--frame-inset) + 7px);
    display: block;
    width: 6px;
    height: 15rem;
    overflow: hidden;
    border: 1px solid var(--ink-3);
    background: repeating-linear-gradient(to bottom, color-mix(in srgb, var(--ink-3) 45%, transparent) 0 1.5rem, transparent 1.5rem 3rem);
    translate: 0 -50%;
  }

  .frame-tb {
    display: flex;
  }

  /* Header: wordmark | numbered sheet nav | CTA (from 80rem) */
  .header-inner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    flex-wrap: nowrap;
  }

  .js .primary-nav,
  .primary-nav {
    display: block;
    flex-basis: auto;
    align-self: stretch;
  }

  .sheet-nav {
    justify-content: flex-end;
    height: 100%;
    column-gap: var(--s-6);
  }

  .nav-link {
    height: 100%;
    align-items: center;
    padding-block: 0;
    font-size: 0.9375rem;
    letter-spacing: 0.01em;
  }

  .nav-no {
    align-self: center;
    padding-top: 0.125rem;
  }

  .js .index-toggle {
    display: none;
  }

  html:not(.js) .site-header {
    position: sticky;
  }

  /* The headline waits for the intro (lettering). Deadline: if the intro has not started 400ms
     after the first frame (slow network), CSS prints the headline. js/main.js sets
     html.intro-on when the intro starts, which cancels the deadline. */
  html.motion-ok:not(.arrived, .motion-fallback) :is(h1, .kicker, .page-kicker)[data-intro] {
    opacity: 0;
  }

  /* Every other hero intro element (the 195+ dimension and the drawing on Home) has a later
     deadline, 1.2s: on a slow network the figure of the hero does not wait for the 2.5s failsafe.
     A late intro then sets the final state at once (instant start). */
  html.motion-ok:not(.arrived, .motion-fallback, .intro-on) [data-intro]:not(.h1-guides) {
    animation: intro-deadline 1ms linear 1200ms forwards;
  }

  html.motion-ok:not(.intro-on) :is(h1, .kicker, .page-kicker)[data-intro] {
    animation: intro-deadline 1ms linear 400ms forwards;
  }

  .sec-head {
    margin-bottom: var(--s-7);
  }

  .spec-row {
    grid-template-columns: 6rem minmax(0, 4fr) minmax(0, 6fr) 2rem;
    column-gap: var(--gutter);
  }

  /* Label, h2 and text share one top line; the actions sit under the text */
  .rfp-inner {
    display: grid;
    grid-template-areas:
      "head text"
      "head actions";
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--gutter);
    align-items: start;
    padding-block: clamp(3rem, 2rem + 4vw, 6rem);
  }

  .rfp-band .sec-head {
    grid-area: head;
    margin-bottom: 0;
  }

  .rfp-text {
    grid-area: text;
  }

  .rfp-band .actions {
    grid-area: actions;
  }

  .tb-grid {
    grid-template-areas:
      "id id id id project project title title title dwg dwg rev"
      "id id id id drawn drawn status status status sheet sheet scale"
      "id id id id index index index index index links links links"
      "legal legal legal legal legal legal legal legal legal legal legal legal";
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }

  .tb-scale {
    display: block;
  }
}

@media (min-width: 80rem) {
  .site-header .header-cta {
    display: inline-flex;
    min-height: 2.5rem;
    margin-left: var(--s-6);
  }
}

/* Scroll-driven scale bar fill: motion allowed and supported only */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .frame-scale-fill {
      animation: scale-fill linear both;
      animation-timeline: scroll(root block);
    }
  }
}

/* The single !important block: reduced motion stops every animation and transition
   (delays too, or staggered rows would still step in one by one) */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  .sheet-index {
    transform: none;
  }
}
