/* ============================================================================
   Architect Cert Prep — stylesheet
   Built on the KistLabs Design System v4.2 (2026-08-21).
   ----------------------------------------------------------------------------
   One file for the whole site. Every page loads this.

   THE SHORT VERSION OF THE SYSTEM

   A blueprint grammar on a dark ground: square-cornered line drawings with
   registration marks at the corners, one steel accent, condensed headings over
   a plain body face. Objects are DRAWN, not filled. The primary button is the
   one solid object on a page.

   Restraint is the credibility signal. The buyer has seen a lot of exam-dump
   sites; gradients, badges and urgency copy read as the opposite of trustworthy.

   ⚠️ THIS REVERSED AN EARLIER DECISION, ON PURPOSE.

   The site used to be light-only, on the reasoning that a dark storefront
   leading into a light exam would jar. The design system overrules that and
   draws the boundary explicitly: the storefront is dark, and the exam player
   keeps its own test-centre chrome, which this system does not touch. The
   tonal shift is now doing a job — it tells the reader they have left the shop
   and entered the exam.

   So: the ten papers and free-exam.html stay light and are NOT styled from
   here. They are self-contained and never load this file. Do not "fix" that.

   FONTS ARE SELF-HOSTED, DELIBERATELY.

   Barlow, Barlow Condensed and IBM Plex Mono are all SIL Open Font License.
   They are served from site/fonts/ rather than from Google, because loading
   them from Google would send every visitor's IP address to a third party on
   page load, which would end the "this site loads nothing from anywhere else"
   position and force a longer, worse privacy page. 104KB for all five faces is
   a cheap price for keeping that.
   ========================================================================== */

/* --- Faces -----------------------------------------------------------------
   font-display:swap means text paints immediately in the fallback face and
   swaps when the webfont lands. The alternative is invisible text for up to
   three seconds on a slow connection. */
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-condensed-600.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/ibm-plex-mono-500.woff2') format('woff2');
}


/* --- Tokens ----------------------------------------------------------------
   Values used more than once live here. Change a colour once, it updates
   everywhere. These are the design system's screen-theme values verbatim. */
:root {
  /* Ground and surfaces. Four levels, no shadows, one fill.
       L0  --bg        page canvas
       L1  transparent + --divider   the default object, a line drawing
       L2  --raised    + --divider   demo plate, table header, evidence half
       L3  --raised    + --control   anything you can act on
     Beyond L3 there is nothing. */
  --bg:       #14171A;
  --raised:   #1B1F23;

  --text:     #E7EDF3;   /* headings and emphasis */
  --dim:      #A9B5C0;   /* body copy */
  --muted:    #97A3AE;   /* meta, captions, mono labels */

  /* Decorative hairlines. No contrast floor, because they carry no meaning. */
  --divider:  rgba(231, 237, 243, 0.16);
  /* Interactive boundaries. Holds 3:1 against the ground, per WCAG 1.4.11. */
  --control:  #6A747E;

  /* One accent, doing one job: what is interactive, or what carries the
     argument. Scores are the only other coloured thing on any page. */
  --accent:   #94BCE3;
  --accent-h: #B5D9FD;   /* hover */
  --accent-a: #749DC4;   /* active */

  /* Score bands. These appear ONLY on scores. Never borrowed for status,
     tags, or charts of anything else. */
  --score-5:  #A6D3AC;
  --score-3:  #DCBD85;
  --score-1:  #AAB5BF;
  --score-0:  #DDA0A0;

  --font-head: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --font-body: 'Barlow', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* Radius: 0 on cards, figures and tables. 4px on buttons, inputs and tags.
     Nothing else. Square corners are most of what makes this read as drawn. */
  --r-control: 4px;

  /* Spacing scale. 4, 8, 12, 16, 24, 32, 48, 64. Section gaps 64 or 100,
     card padding 24, sibling gaps 16 or 24. Never an odd value. */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-6: 24px; --s-8: 32px; --s-12: 48px; --s-16: 64px;

  /* Two widths, not one.
       --frame    the outer column. Header, footer, tables, panels span this.
       --measure  the widest a line of PROSE may get, in ch so it scales with
                  each element's own font size and gives consistent characters
                  per line rather than consistent pixels. */
  --frame:   1100px;
  --measure: 70ch;

  /* Motion. Interface motion is short and functional. Nothing here loops. */
  --t-fast: 160ms;
  --t-std:  240ms;
  --ease:   cubic-bezier(0.2, 0, 0, 1);
}


/* --- Reset -----------------------------------------------------------------
   border-box counts padding INSIDE a stated width. Without it a 100%-wide box
   with padding is wider than its container and the page scrolls sideways. */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, p, ul, ol, figure { margin: 0; }


/* --- Page ------------------------------------------------------------------ */
body {
  font-family: var(--font-body);
  /* 17px on a phone, 19px from about 900px up. This is a reading site and the
     audience skews senior, so type size is the lever that widens the column
     without pushing lines past a readable length. At a fixed 19px a 375px
     screen fits ~36 characters, which reads as a stack of fragments. */
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem);
  line-height: 1.65;
  color: var(--dim);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.wrap {
  max-width: var(--frame);
  margin: 0 auto;
  padding: 0 var(--s-6);
}

/* Prose caps at the measure but keeps the frame's LEFT edge rather than
   centring inside it. Everything shares one left edge; only the right edge
   varies. That is what stops the text reading as a ribbon floating in space. */
main .wrap > p,
main .wrap > ul,
main .wrap > ol,
main .wrap > h2,
main .wrap > h3 { max-width: var(--measure); }

main .wrap > h1 { max-width: 20ch; }   /* large type, fewer characters */

/* Full-frame blocks still have to keep their TEXT readable, or a panel ends up
   with 95-character lines while the prose beside it sits at 70. Cap the text,
   not the box. */
.claim > p,
.panel > p,
.buy > p,
.question .scenario p,
.question .option-text,
.question li,
.rationale,
.evidence,
.site-footer .disclaimer,
.lede,
.small { max-width: var(--measure); }

/* The spec table genuinely wants full width: two columns of short phrases,
   not prose. Cramping it forces wrapping that makes it harder to scan. */
.spec { max-width: none; }

/* Retired, kept so any page still using it does not break. */
.wrap-wide { max-width: var(--frame); }


/* --- Type ------------------------------------------------------------------
   Headings are Barlow Condensed 600 with negative tracking. Condensed type
   wants to be tighter than default; at these sizes the default gaps read as
   loose. Sizes clamp so the whole scale moves together with the viewport. */
h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--text);
  line-height: 1.08;
}

h1 {
  font-size: clamp(2.5rem, 1.6rem + 3.6vw, 3.875rem);   /* 40px → 62px */
  letter-spacing: -0.022em;
  margin-bottom: var(--s-6);
}

h2 {
  font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.25rem);  /* 28px → 36px */
  letter-spacing: -0.018em;
  line-height: 1.1;
  margin-top: var(--s-16);
  margin-bottom: var(--s-4);
}

h3 {
  font-size: clamp(1.3rem, 1.2rem + 0.4vw, 1.5rem);     /* ~21px → 24px */
  letter-spacing: -0.015em;
  margin-top: var(--s-8);
  margin-bottom: var(--s-3);
}

p { margin-bottom: var(--s-4); }
p:last-child { margin-bottom: 0; }

ul, ol { margin-bottom: var(--s-4); padding-left: 1.3em; }
li { margin-bottom: var(--s-2); }

strong { color: var(--text); font-weight: 500; }
em { font-style: italic; }

/* The one line of evidence under a page title. Larger than body, still prose. */
.lede {
  font-size: 1.16em;
  color: var(--dim);
  margin-bottom: var(--s-8);
}

.small { font-size: 0.86em; }
.mt-0  { margin-top: 0; }

/* Mono labels. 0.08em tracking, uppercase, small. Used for anything that is
   data rather than prose: table headers, figure captions, meta lines. */
.label, .spec th, .site-footer .copyright {
  font-family: var(--font-mono);
  font-size: 0.72em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}


/* --- Links and focus ------------------------------------------------------- */
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-h); text-decoration: underline; }

/* Focus is a 2px accent ring at 2px offset. Never removed, never replaced by
   a colour change alone. :focus-visible means it shows for keyboard users and
   not on mouse clicks. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--s-2);
  background: var(--accent);
  color: var(--bg);
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-control);
  font-weight: 500;
  z-index: 10;
}
.skip-link:focus { left: var(--s-4); }


/* --- Masthead --------------------------------------------------------------
   Architect Cert Prep leads, because that is the name on the domain and the
   name someone searched for. The KistLabs ring sits beside it and the wordmark
   under it, so the company is recognisable across every page — and, more
   practically, so a buyer who later sees KISTLABS on a card statement or an
   invoice number knows what it is.

   Per the system's lockup rule, the inner arc keeps its steel accent in every
   colour lockup. The ring stays in the foreground colour, while "Labs" keeps
   the same steel accent in the wordmark. */
.site-header {
  border-bottom: 1px solid var(--divider);
  padding: var(--s-4) 0;
  margin-bottom: var(--s-12);
}
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-6);
}

.brand-block {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-right: auto;      /* pushes the nav hard right */
  text-decoration: none;
}

/* The mark. The outer ring follows the lockup foreground; the inner arc keeps
   the steel accent, including on hover. */
.brand-mark {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  color: var(--dim);
}
.brand-mark path + path { stroke: var(--accent); }
.brand-block:hover .brand-mark { color: var(--text); }

.brand {
  display: block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.32em;
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--text);
  text-decoration: none;
}
.brand:hover { color: var(--text); text-decoration: none; }

.brand-text { display: block; }

/* The wordmark. Barlow Condensed 600, ONE WORD, CAMEL CASE — so no
   text-transform here; uppercasing it would destroy the camel case the spec
   requires. Kist in the foreground colour, Labs in the accent: the only place
   in the system where two colours sit inside one word. */
.brand-by {
  display: block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.82em;
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--muted);
  margin-top: 1px;
}
.brand-by b { font-weight: 600; color: var(--dim); }
.brand-by i { font-style: normal; font-weight: 600; color: var(--accent); }

.site-nav { display: flex; flex-wrap: wrap; gap: var(--s-6); }
.site-nav a {
  font-family: var(--font-mono);
  font-size: 0.72em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}
.site-nav a:hover { color: var(--accent-h); text-decoration: none; }
.site-nav a[aria-current="page"] { color: var(--text); }


/* --- Registration marks ----------------------------------------------------
   The grammar of the system: square-cornered line drawings with a tick at each
   corner, like a print registration mark. Drawn with one pseudo-element and
   eight background gradients — four L-shaped corners — so no extra markup is
   needed and nothing can drift out of alignment.

   inset:-1px puts the marks ON the border rather than inside it. */
.claim, .panel, .buy, .question, .tier, .spec-wrap { position: relative; }

.claim::before, .panel::before, .buy::before, .question::before, .tier::before {
  content: "";
  position: absolute;
  inset: -1px;
  pointer-events: none;
  --reg: var(--accent);
  background:
    linear-gradient(var(--reg) 0 0) 0    0    / 9px 1px no-repeat,
    linear-gradient(var(--reg) 0 0) 0    0    / 1px 9px no-repeat,
    linear-gradient(var(--reg) 0 0) 100% 0    / 9px 1px no-repeat,
    linear-gradient(var(--reg) 0 0) 100% 0    / 1px 9px no-repeat,
    linear-gradient(var(--reg) 0 0) 0    100% / 9px 1px no-repeat,
    linear-gradient(var(--reg) 0 0) 0    100% / 1px 9px no-repeat,
    linear-gradient(var(--reg) 0 0) 100% 100% / 9px 1px no-repeat,
    linear-gradient(var(--reg) 0 0) 100% 100% / 1px 9px no-repeat;
}


/* --- Objects ---------------------------------------------------------------
   L1: transparent, hairline-framed, square. The default object on the page.
   Never filled, never rounded. */
.claim, .panel, .buy {
  border: 1px solid var(--divider);
  background: transparent;
  padding: var(--s-6);
  margin: var(--s-8) 0;
}

/* The one highlighted callout gets the raised fill (L2) so it separates from
   the ground without a shadow. Nothing casts on this ground. */
.claim {
  background: var(--raised);
  font-size: 1.06em;
}
.claim strong { color: var(--accent); font-weight: 500; }


/* --- Buttons ---------------------------------------------------------------
   Primary is the ONE solid object on a page: accent fill, ground-colour text.
   One per view. Secondary is a hairline outline. 44px minimum height, which is
   the smallest comfortable tap target on a phone. */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.92em;
  line-height: 1.2;
  padding: 13px var(--s-6);
  min-height: 44px;
  border-radius: var(--r-control);
  border: 1px solid transparent;   /* so .btn and .btn-secondary match height */
  background: var(--accent);
  color: var(--bg);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.btn:hover { background: var(--accent-h); color: var(--bg); text-decoration: none; }
.btn:active { background: var(--accent-a); }

.btn-secondary {
  background: transparent;
  color: var(--accent);
  border-color: var(--control);
}
.btn-secondary:hover {
  background: transparent;
  color: var(--accent-h);
  border-color: var(--accent);
}

/* Two buttons in a row need a real gap; the whitespace between the tags is
   about 4px and reads as a mistake. The phone query below stacks them and
   resets this. */
.btn + .btn { margin-left: var(--s-3); }


/* --- Tiers -----------------------------------------------------------------
   Two licences side by side, so they read as a pair and the difference between
   them is visible in one glance. They were stacked panels separated by a
   subheading, which made them look like two unrelated offers.

   ⚠️ Exactly ONE solid button on this page: the individual tier's. The team
   tier and the free-paper link are outlines. That is the design system's rule
   (the primary button is the one solid object, one per view) and it is also
   what the reference does — on Mercury's pricing page only the entry plan's
   button is filled; Plus and Pro are subtle. The two agree, so nothing had to
   be traded away. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s-4);
}

.tiers {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-6);
  margin: var(--s-6) 0 var(--s-8);
}

/* L1 object: transparent, hairline-framed, square, registration marks. Same
   grammar as every other object on the site; see the marks block above. */
.tier {
  position: relative;
  border: 1px solid var(--divider);
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
}

.tier-name {
  font-family: var(--font-mono);
  font-size: 0.72em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s-2);
}

/* Buttons sit together, then the list. margin-top:auto on the list wrapper
   would push it down; instead the buttons carry a fixed gap so both tiers line
   their lists up even when one has two buttons and the other has one. */
.tier-actions { margin: var(--s-4) 0 var(--s-6); }
.tier-actions .btn { display: block; width: 100%; text-align: center; }
.tier-actions .btn + .btn { margin-left: 0; margin-top: var(--s-3); }

.tier-lead {
  color: var(--text);
  font-size: 0.92em;
  margin-bottom: var(--s-3);
}

/* Checked list. The tick is a pseudo-element rather than a character in the
   markup, so a screen reader reads the item and not "check mark" seven times. */
.tier-list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.9em;
}
.tier-list li {
  position: relative;
  padding-left: 1.6em;
  margin-bottom: var(--s-3);
}
.tier-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 9px;
  height: 5px;
  border-left: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  transform: rotate(-45deg);
}


/* --- Buy panels ------------------------------------------------------------ */
.price {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 2.4em;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.price-note {
  color: var(--muted);
  font-size: 0.84em;
  margin-top: var(--s-2);
}


/* --- Tables ----------------------------------------------------------------
   Mono uppercase headers on a divider rule, hairline row rules, tabular
   figures so columns of numbers line up. */
.spec {
  width: 100%;
  border-collapse: collapse;
  margin: var(--s-6) 0;
  font-size: 0.9em;
}
.spec th, .spec td {
  text-align: left;
  vertical-align: top;
  padding: var(--s-3) var(--s-4) var(--s-3) 0;
  border-bottom: 1px solid var(--divider);
}
.spec th {
  color: var(--muted);
  font-weight: 400;
  white-space: nowrap;
  width: 1%;
  padding-right: var(--s-8);
}
.spec td { color: var(--dim); }
.spec tr:last-child th, .spec tr:last-child td { border-bottom: 0; }

/* Wide content scrolls inside its own box rather than making the page scroll
   sideways. */
.scroll-x { overflow-x: auto; }


/* --- The sample question ---------------------------------------------------
   Deliberately plainer than the rest of the page. It should look like the
   exam, not like marketing. */
.question {
  border: 1px solid var(--divider);
  padding: var(--s-6);
  margin: var(--s-8) 0;
}
.question .scenario { margin-bottom: var(--s-6); }
.question .scenario p { margin-bottom: var(--s-3); }

.option {
  border-top: 1px solid var(--divider);
  padding-top: var(--s-4);
  margin-top: var(--s-4);
}
.option-text { margin: 0; font-size: 0.94em; }

/* Rationale and evidence sit under the options. Evidence is the citation, so
   it is mono — it is a reference, not prose. */
.rationale { font-size: 0.94em; }
.evidence {
  font-family: var(--font-mono);
  font-size: 0.8em;
  line-height: 1.6;
  color: var(--muted);
  border-left: 2px solid var(--divider);
  padding-left: var(--s-4);
  margin: var(--s-4) 0;
}


/* --- Scores ----------------------------------------------------------------
   The only other coloured thing on any page. Colour is never the only signal:
   every score carries its number, so this reads correctly in greyscale and to
   anyone who cannot separate the hues. */
.score {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.92em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.score-5 { color: var(--score-5); }
.score-3 { color: var(--score-3); }
.score-1 { color: var(--score-1); }
.score-0 { color: var(--score-0); }

/* Headings that announce a score band carry the band colour, because the
   heading IS the score. */
h3 .score-5, h3 .score-3, h3 .score-1, h3 .score-0 { font-size: inherit; }


/* --- About -----------------------------------------------------------------
   The About page is evidence-led rather than biographical: what was matched,
   how the set was constructed, and how a reader can verify the work. */
.about-page .site-header { margin-bottom: 0; }

.about-hero {
  padding: var(--s-16) 0;
  border-bottom: 1px solid var(--divider);
}
.about-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(300px, 0.85fr);
  gap: clamp(var(--s-12), 8vw, 100px);
  align-items: end;
}
.about-hero-copy h1 { max-width: 13ch; }
.about-hero-copy .lede {
  max-width: 58ch;
  margin-bottom: 0;
}

.about-motion-art {
  position: relative;
  margin: 0;
  aspect-ratio: 1;
  min-height: 280px;
  perspective: 560px;
  perspective-origin: 50% 48%;
}
.about-motion-art svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  transform-box: view-box;
  transform-origin: center;
  transform-style: preserve-3d;
  animation: motion-scene 11s var(--ease) infinite;
}
.about-motion-art circle,
.about-motion-art path {
  fill: none;
  vector-effect: non-scaling-stroke;
}
.motion-guides {
  stroke: var(--divider);
  stroke-width: 1;
  stroke-dasharray: 2 7;
  transform-box: view-box;
  transform-origin: center;
  animation: motion-guide-plane 16s linear infinite;
}
.motion-guides path { opacity: 0.55; }
.motion-depth-orbit {
  transform-box: view-box;
  transform-origin: 180px 180px;
  transform-style: preserve-3d;
  will-change: transform;
}
.motion-depth-orbit circle {
  stroke: var(--accent);
  stroke-width: 1.1;
  stroke-dasharray: 1.5 9;
  stroke-linecap: round;
  opacity: 0.68;
}
.motion-depth-a { animation: motion-depth-a 12s linear infinite; }
.motion-depth-b { animation: motion-depth-b 17s linear infinite reverse; }
.motion-depth-b circle { opacity: 0.5; }
.motion-depth-c { animation: motion-depth-c 9s linear infinite; }
.motion-depth-c circle {
  stroke: var(--dim);
  stroke-dasharray: 1 8;
  opacity: 0.6;
}
.motion-depth-d { animation: motion-depth-d 14s linear infinite reverse; }
.motion-depth-d circle {
  stroke-dasharray: 1 6;
  opacity: 0.45;
}
.motion-orbit {
  transform-box: view-box;
  transform-origin: 180px 180px;
  transform-style: preserve-3d;
  will-change: transform;
}
.motion-orbit circle {
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: square;
}
.motion-orbit-outer {
  animation: motion-orbit-x 18s linear infinite;
}
.motion-orbit-outer circle { stroke-dasharray: 178 46 62 44 96 366; }
.motion-orbit-inner {
  animation: motion-orbit-y 13s linear infinite reverse;
}
.motion-orbit-inner circle {
  opacity: 0.68;
  stroke-dasharray: 84 34 42 52 110 256;
}
.motion-core {
  stroke: var(--dim);
  stroke-width: 1;
  transform-box: view-box;
  transform-origin: 180px 180px;
  animation: motion-core-float 4.8s var(--ease) infinite;
  will-change: transform;
}
.motion-core circle:last-of-type {
  stroke: var(--accent);
  stroke-width: 1.5;
}
.motion-core path:nth-of-type(1),
.motion-core path:nth-of-type(2) { stroke: var(--control); }
.motion-core path:nth-of-type(3),
.motion-core path:nth-of-type(4) { stroke: var(--accent); }
.motion-nodes circle {
  fill: var(--bg);
  stroke: var(--accent);
  stroke-width: 1.5;
  animation: motion-node 3.2s var(--ease) infinite;
}
.motion-node-b { animation-delay: -0.8s !important; }
.motion-node-c { animation-delay: -1.6s !important; }
.motion-node-d { animation-delay: -2.4s !important; }
.motion-node-e { animation-delay: -1.2s !important; }
.motion-scan {
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 30 186;
  animation: motion-scan 3.6s linear infinite;
}

@keyframes motion-scene {
  0%, 100% { transform: rotateX(11deg) rotateY(-14deg); }
  50% { transform: rotateX(-10deg) rotateY(15deg); }
}
@keyframes motion-guide-plane {
  from { transform: rotateZ(0deg) translateZ(-24px); }
  to { transform: rotateZ(360deg) translateZ(-24px); }
}
@keyframes motion-orbit-x {
  from { transform: rotateX(58deg) rotateZ(0deg); }
  to { transform: rotateX(58deg) rotateZ(360deg); }
}
@keyframes motion-orbit-y {
  from { transform: rotateY(62deg) rotateZ(0deg); }
  to { transform: rotateY(62deg) rotateZ(360deg); }
}
@keyframes motion-depth-a {
  from { transform: rotateX(72deg) rotateZ(0deg); }
  to { transform: rotateX(72deg) rotateZ(360deg); }
}
@keyframes motion-depth-b {
  from { transform: rotateY(70deg) rotateZ(0deg); }
  to { transform: rotateY(70deg) rotateZ(360deg); }
}
@keyframes motion-depth-c {
  from { transform: rotateX(48deg) rotateY(42deg) rotateZ(0deg); }
  to { transform: rotateX(48deg) rotateY(42deg) rotateZ(360deg); }
}
@keyframes motion-depth-d {
  from { transform: rotateX(-55deg) rotateY(36deg) rotateZ(0deg); }
  to { transform: rotateX(-55deg) rotateY(36deg) rotateZ(360deg); }
}
@keyframes motion-core-float {
  0%, 100% { transform: translateZ(34px) scale(1); }
  50% { transform: translateZ(60px) scale(1.055); opacity: 0.76; }
}
@keyframes motion-node {
  50% { r: 7px; opacity: 0.55; }
}
@keyframes motion-scan { to { stroke-dashoffset: -216; } }

.about-story {
  display: grid;
  grid-template-columns: minmax(150px, 0.34fr) minmax(0, 1fr);
  gap: var(--s-12);
  padding-top: 100px;
}
.about-section-label {
  display: flex;
  gap: var(--s-3);
  align-items: baseline;
  align-self: start;
  padding-top: var(--s-2);
  border-top: 1px solid var(--divider);
  font-family: var(--font-mono);
  font-size: 0.68em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.about-section-label span { color: var(--accent); }
.about-section-label p { margin: 0; }
.about-section-copy {
  max-width: var(--measure);
}
.about-section-copy h2,
.about-method-heading h2,
.about-next h2 {
  margin-top: 0;
}

.about-pullquote {
  position: relative;
  margin: var(--s-8) 0;
  padding: var(--s-6) 0 var(--s-6) var(--s-6);
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.about-pullquote::before {
  content: "";
  position: absolute;
  left: 0;
  top: var(--s-6);
  bottom: var(--s-6);
  width: 2px;
  background: var(--accent);
}
.about-pullquote p {
  max-width: 30ch;
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(1.65rem, 1.35rem + 1.2vw, 2.15rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.015em;
  color: var(--text);
}

.about-method {
  margin-top: 100px;
  padding-top: var(--s-12);
  border-top: 1px solid var(--divider);
}
.about-method-heading {
  display: grid;
  grid-template-columns: minmax(150px, 0.34fr) minmax(0, 1fr);
  gap: var(--s-12);
  margin-bottom: var(--s-8);
}
.about-method-heading > div:last-child { max-width: var(--measure); }

.about-method-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: none !important;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.about-method-grid li {
  margin: 0;
  padding: var(--s-6);
  border-right: 1px solid var(--divider);
}
.about-method-grid li:first-child { padding-left: 0; }
.about-method-grid li:last-child {
  padding-right: 0;
  border-right: 0;
}
.about-method-number {
  display: block;
  margin-bottom: var(--s-12);
  font-family: var(--font-mono);
  font-size: 0.68em;
  letter-spacing: 0.06em;
  color: var(--accent);
}
.about-method-grid h3 { margin-top: 0; }
.about-method-grid p {
  margin: 0;
  font-size: 0.9em;
  line-height: 1.55;
}

.about-origin-note {
  display: grid;
  grid-template-columns: minmax(150px, 0.34fr) minmax(0, var(--measure));
  gap: var(--s-12);
  padding: var(--s-8) 0 0;
}
.about-origin-note .label {
  padding-top: 0.3em;
  color: var(--accent);
}

.about-next {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(260px, 0.75fr);
  gap: var(--s-12);
  align-items: end;
  margin-top: 100px;
  padding: var(--s-12);
  border: 1px solid var(--divider);
  background: var(--raised);
}
.about-next::before {
  content: "";
  position: absolute;
  inset: -1px;
  pointer-events: none;
  background:
    linear-gradient(var(--accent) 0 0) 0 0 / 12px 1px no-repeat,
    linear-gradient(var(--accent) 0 0) 0 0 / 1px 12px no-repeat,
    linear-gradient(var(--accent) 0 0) 100% 100% / 12px 1px no-repeat,
    linear-gradient(var(--accent) 0 0) 100% 100% / 1px 12px no-repeat;
}
.about-next > div > p:last-child { margin-bottom: 0; }
.about-next-action { margin: 0; }
.about-next-action .btn { width: 100%; text-align: center; }
.about-next-action span {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--font-mono);
  font-size: 0.68em;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-align: center;
  text-transform: uppercase;
  color: var(--muted);
}

.about-contact {
  margin-top: 100px;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.about-contact summary {
  display: flex;
  justify-content: space-between;
  gap: var(--s-6);
  align-items: center;
  min-height: 88px;
  padding: var(--s-4) 0;
  cursor: pointer;
  list-style: none;
}
.about-contact summary::-webkit-details-marker { display: none; }
.about-contact summary:hover .about-contact-title { color: var(--accent-h); }
.about-contact summary .eyebrow {
  display: block;
  margin-bottom: var(--s-1);
}
.about-contact-title {
  display: block;
  font-family: var(--font-head);
  font-size: clamp(1.35rem, 1.2rem + 0.6vw, 1.65rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--text);
  transition: color var(--t-fast) var(--ease);
}
.about-contact-toggle {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-mono);
  font-size: 0.68em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.about-contact-toggle::before { content: "Show details"; }
.about-contact-toggle::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 1px solid var(--muted);
  border-bottom: 1px solid var(--muted);
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--t-std) var(--ease);
}
.about-contact[open] .about-contact-toggle::before { content: "Hide details"; }
.about-contact[open] .about-contact-toggle::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}
.about-contact-panel {
  max-width: var(--measure);
  margin-left: min(34%, 360px);
  padding: var(--s-4) 0 var(--s-8);
}


/* --- Article index ---------------------------------------------------------
   Editorial rows keep a growing library scannable without turning every link
   into a separate floating card. */
.articles-page .site-header { margin-bottom: 0; }

.articles-hero {
  padding: var(--s-16) 0;
  border-bottom: 1px solid var(--divider);
}
.articles-hero .lede {
  max-width: 58ch;
  margin-bottom: 0;
}

.article-meta,
.article-number,
.article-read,
.article-count {
  font-family: var(--font-mono);
  font-size: 0.72em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.article-library { padding-top: var(--s-16); }
.article-library-heading {
  display: flex;
  justify-content: space-between;
  gap: var(--s-6);
  align-items: end;
  margin-bottom: var(--s-8);
}
.article-library-heading h2 {
  max-width: 18ch;
  margin: 0;
}
.article-count {
  flex: 0 0 auto;
  margin: 0 0 var(--s-1);
  color: var(--muted);
}
.article-count strong {
  margin-right: var(--s-2);
  color: var(--text);
  font-size: 1.35em;
  font-variant-numeric: tabular-nums;
}

.article-list {
  max-width: none !important;
  padding: 0;
  margin: 0;
  list-style: none;
  border-top: 1px solid var(--divider);
}
.article-list li {
  margin: 0;
  border-bottom: 1px solid var(--divider);
}
.article-list-link {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) max-content;
  gap: var(--s-6);
  align-items: start;
  min-height: 184px;
  padding: var(--s-8) var(--s-4);
  color: inherit;
  text-decoration: none;
  transition: background var(--t-fast) var(--ease);
}
.article-list-link:hover {
  color: inherit;
  background: var(--raised);
  text-decoration: none;
}
.article-number {
  padding-top: 0.35em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.article-list-copy { display: block; }
.article-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-6);
  margin-bottom: var(--s-3);
  color: var(--muted);
}
.article-meta span + span::before {
  content: "/";
  margin-right: var(--s-6);
  color: var(--control);
}
.article-title {
  display: block;
  max-width: 24ch;
  margin-bottom: var(--s-3);
  color: var(--text);
  font-family: var(--font-head);
  font-size: clamp(1.55rem, 1.3rem + 1vw, 2rem);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.1;
  transition: color var(--t-fast) var(--ease);
}
.article-list-link:hover .article-title { color: var(--accent-h); }
.article-description {
  display: block;
  max-width: var(--measure);
  color: var(--dim);
  font-size: 0.92em;
  line-height: 1.55;
}
.article-read {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  padding-top: 0.35em;
  color: var(--accent);
  white-space: nowrap;
}
.article-read span {
  display: inline-block;
  font-size: 1.35em;
  line-height: 0.7;
  transition: transform var(--t-fast) var(--ease);
}
.article-list-link:hover .article-read span { transform: translateX(var(--s-1)); }

.articles-practice {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.8fr);
  gap: var(--s-12);
  align-items: end;
  margin-top: 100px;
  padding: var(--s-12) 0;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.articles-practice h2 {
  max-width: 18ch;
  margin: 0;
}
.articles-practice-copy p { margin-bottom: var(--s-6); }


/* --- FAQ -------------------------------------------------------------------
   Seven answers stacked open was a wall of text at the foot of the page. These
   are <details>, so they collapse with NO JavaScript — the site still ships
   zero script, which is worth more than an "expand all" button.

   The <h3> stays inside the <summary>. The spec allows exactly one heading
   there, and keeping it means the document outline and the search-engine view
   are unchanged; only the visual density moved. Collapsed content is still in
   the DOM, so nothing is hidden from indexing. */
.faq {
  border-top: 1px solid var(--divider);
  max-width: var(--measure);
}
.faq:last-of-type { border-bottom: 1px solid var(--divider); }

/* ⚠️ The padding lives on the SUMMARY, not on the .faq wrapper. Only the
   summary is clickable, so padding on the wrapper looks identical and leaves a
   21px tap target — under the 24px WCAG 2.5.8 minimum and far under the 44px
   this site uses for buttons. Measured at 375px before it was moved. */
.faq summary {
  cursor: pointer;
  list-style: none;              /* hides the default triangle */
  display: flex;
  align-items: baseline;
  gap: var(--s-4);
  padding: var(--s-4) 0;
  min-height: 44px;
}
.faq summary::-webkit-details-marker { display: none; }

.faq summary h3 {
  display: inline;
  margin: 0;
  font-size: 1.12em;
  color: var(--text);
  flex: 1 1 auto;
}
.faq summary:hover h3 { color: var(--accent-h); }

/* The chevron. Rotates on open. transform is safe to animate — it does not
   move layout or reflow anything, which is the system's rule on motion. */
.faq summary::after {
  content: "";
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  margin-top: 0.35em;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg);
  transition: transform var(--t-std) var(--ease);
}
.faq[open] summary::after { transform: rotate(-135deg); }

.faq > p { margin-top: var(--s-3); }
/* Bottom breathing room only when open, so a closed row stays compact. */
.faq[open] > p:last-child { margin-bottom: 0; padding-bottom: var(--s-4); }

/* --- Footer ---------------------------------------------------------------- */
.site-footer {
  margin-top: var(--s-16);
  border-top: 1px solid var(--divider);
  padding: var(--s-8) 0 var(--s-12);
  color: var(--muted);
  font-size: 0.82em;
  line-height: 1.6;
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  margin-bottom: var(--s-6);
}
.footer-nav a {
  font-family: var(--font-mono);
  font-size: 0.92em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.footer-nav a:hover { color: var(--accent-h); }

.site-footer .disclaimer { margin-bottom: var(--s-4); }

/* Business name and year. There is no postal address anywhere, by decision:
   Polar is merchant of record, so the buyer's contract of sale is with Polar
   and Polar's details appear at checkout and on the receipt. See terms.html. */
.site-footer .copyright { color: var(--muted); }


/* --- Phones ---------------------------------------------------------------- */
@media (max-width: 40rem) {
  .wrap { padding: 0 var(--s-4); }

  .site-header { padding: var(--s-3) 0; margin-bottom: var(--s-8); }
  .site-header .wrap { gap: var(--s-2) var(--s-4); }
  .brand-mark { width: 26px; height: 26px; }
  .site-nav { gap: var(--s-4); width: 100%; }

  h2 { margin-top: var(--s-12); }

  .claim, .panel, .buy, .question, .tier { padding: var(--s-4); }

  /* Tiers stack. Side by side at 375px would give each about 160px, which is
     narrower than the price is wide. */
  .tiers { grid-template-columns: 1fr; gap: var(--s-4); }

  /* Buttons go full width: easier to hit, and it stops two of them wrapping
     into an awkward stack of different lengths. */
  .btn { display: block; width: 100%; text-align: center; }
  .btn + .btn { margin-left: 0; margin-top: var(--s-3); }

  /* The spec table becomes two stacked rows per item rather than two columns,
     because a nowrap header column plus a sentence does not fit in 375px. */
  .spec th, .spec td { display: block; width: auto; padding-right: 0; }
  .spec th { border-bottom: 0; padding-bottom: 0; }
  .spec td { padding-top: var(--s-1); }

  .articles-hero { padding: var(--s-12) 0; }

  .article-library { padding-top: var(--s-12); }
  .article-library-heading {
    align-items: end;
    gap: var(--s-4);
  }
  .article-count { text-align: right; }
  .article-list-link {
    grid-template-columns: 32px minmax(0, 1fr);
    gap: var(--s-3);
    min-height: 0;
    padding: var(--s-6) 0;
  }
  .article-read {
    grid-column: 2;
    padding: 0;
  }
  .article-meta { gap: var(--s-2) var(--s-3); }
  .article-meta span + span::before { margin-right: var(--s-3); }

  .articles-practice {
    grid-template-columns: 1fr;
    gap: var(--s-6);
    margin-top: var(--s-16);
    padding: var(--s-8) 0;
  }

  .about-hero { padding: var(--s-12) 0; }
  .about-hero-grid,
  .about-story,
  .about-method-heading,
  .about-origin-note,
  .about-next {
    grid-template-columns: 1fr;
  }
  .about-hero-grid { gap: var(--s-8); }
  .about-story { gap: var(--s-6); padding-top: var(--s-16); }
  .about-method { margin-top: var(--s-16); padding-top: var(--s-8); }
  .about-method-heading { gap: var(--s-6); }
  .about-method-grid { grid-template-columns: 1fr; }
  .about-method-grid li {
    padding: var(--s-6) 0;
    border-right: 0;
    border-bottom: 1px solid var(--divider);
  }
  .about-method-grid li:last-child { border-bottom: 0; }
  .about-method-number { margin-bottom: var(--s-4); }
  .about-origin-note { gap: var(--s-3); }
  .about-next {
    gap: var(--s-8);
    margin-top: var(--s-16);
    padding: var(--s-6);
  }
  .about-motion-art { min-height: 0; max-width: 420px; margin: 0 auto; }
  .about-contact { margin-top: var(--s-16); }
  .about-contact summary { min-height: 76px; }
  .about-contact-toggle::before { content: "Show"; }
  .about-contact[open] .about-contact-toggle::before { content: "Hide"; }
  .about-contact-panel { margin-left: 0; padding-top: var(--s-2); }
}


/* --- Reduced motion --------------------------------------------------------
   Nothing here loops or animates layout, so this only has to neutralise the
   colour transitions. Nothing disappears and nothing reflows. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* --- Print -----------------------------------------------------------------
   Dark for screens, paper for print. The same structure inverted, not a second
   system. Ground #F4F1EA, ink #1A1A1A, accent #14507A — which is also exactly
   what the exam papers use, so a printed page from the site and a printed
   paper look like they came from the same place. */
@media print {
  :root {
    --bg:      #F4F1EA;
    --raised:  #FFFFFF;
    --text:    #1A1A1A;
    --dim:     #1A1A1A;
    --muted:   #5A5A5A;
    --divider: #DDD8CD;
    --control: #8A8A8A;
    --accent:  #14507A;
  }
  body { font-size: 11pt; }
  .site-header, .site-nav, .skip-link, .btn { display: none; }
  .claim::before, .panel::before, .buy::before, .question::before { display: none; }
  a { color: var(--accent); }
  /* Show where a link went, since a printed page cannot be clicked. */
  main a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-family: var(--font-mono);
    font-size: 0.8em;
    color: var(--muted);
  }
}
