/* =========================================================================
   Laytr — laytr.app
   Direction B "The Index" v2, on the web.

   Every value here traces to docs/DESIGN_SYSTEM.md. The rules that document
   states as non-negotiable are non-negotiable here too:

     - Two accents with strict jobs. --mark is identity; --signal is due-time
       pressure and nothing else, ever. --mark is never a text colour.
     - No shadows. Separation is hairline rules and whitespace. The single
       exception is the sticker chip's hard die-cut offset, which is a printed
       artefact, not elevation.
     - Mounts are radius 2. Objects sit on plinths; they do not float.
     - The mono catalog layer never exceeds caption size and is always garnish.
       If you must read it to trust or decide, it gets the body voice
       (DESIGN_SYSTEM §3, "readability floor").
     - Base-4 spacing only.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------------------- */

:root {
  /* Colour — the light values from DESIGN_SYSTEM §2, verbatim. */
  --field: #f6f5f1;
  --plinth: #ffffff;
  --ink: #141414;
  --ink-muted: #6e6c65;
  --laytr-mark: #c6d92e;
  --on-mark: #141414;
  --signal: #c63e18;
  --on-signal: #ffffff;
  --rule: #dddbd2;

  /* The duotone treatment is "ink through inverted luminance on field".
     On the web that is a CSS filter over the release captures, used only
     where a screen is decoration rather than evidence. */
  --exhibit-strength: 1;

  /* Spacing — base 4, exactly the steps LaytrSpacing offers. */
  --s-xs: 4px;
  --s-s: 8px;
  --s-m: 12px;
  --s-l: 16px;
  --s-xl: 24px;
  --s-xxl: 32px;
  --page-margin: 20px;

  /* Shape */
  --r-mount: 2px;
  --r-thumb: 4px;
  --r-sheet: 12px;
  --hairline: 1px;

  /* Type */
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
    "Liberation Mono", monospace;
  --serif: "New York", ui-serif, Georgia, "Times New Roman", serif;

  /* Layout */
  --measure: 34rem; /* ~68 characters: the reading measure for body copy */
  --shell: 1180px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --field: #121212;
    --plinth: #1c1c1e;
    --ink: #f2f1ec;
    --ink-muted: #8e8c85;
    --laytr-mark: #d6e84a;
    --on-mark: #141414;
    --signal: #f0603a;
    --on-signal: #121212;
    --rule: #2c2c2e;

    /* "Exhibits sit back": luminance inversion makes bright elements read
       about twice as loud on ink, so the drawing layer drops to 72% in dark
       exactly as DuotoneThumbnail does in the app (DESIGN_SYSTEM §2). */
    --exhibit-strength: 0.72;
  }
}

/* The increased-contrast variants that ship in the app's asset catalog. */
@media (prefers-contrast: more) {
  :root {
    --ink-muted: #55534d;
    --signal: #a83412;
    --rule: #b8b6ad;
  }
}

@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
  :root {
    --ink-muted: #aba9a2;
    --signal: #ff7a55;
    --rule: #48484a;
  }
}

/* -------------------------------------------------------------------------
   2. Reset and base
   ------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--field);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
}

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

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

a:hover {
  text-decoration-color: var(--laytr-mark);
}

/* The one focus treatment, everywhere.

   Ink, not chartreuse. Chartreuse is the identity accent and it is what
   selection wears, so it was the instinctive choice here -- but measured, it is
   1.44:1 against the light field, which fails WCAG 2.2 SC 1.4.11 (non-text
   contrast, 3:1) and is genuinely hard to see. Ink clears 11:1 or better on
   every surface this site puts a focusable element on, in both colour schemes.
   website/tools/test_contrast.py holds that true.

   Two rings, not one. An ink ring alone is fine against the page and against a
   mount, but a focusable element can be filled with chartreuse -- a selected
   tab, a .btn--mark -- and in dark mode ink is near-white, which is 1.20:1 on
   chartreuse. So an inner ring in the page colour always separates the ink ring
   from whatever the element is filled with, and the measured pair is ink on
   field in every case.

   The inner ring is a box-shadow with zero blur: a printed ring, the same
   licence the sticker chip's die-cut offset has, not elevation. The outline
   follows the element's own shape, so capsule buttons and die-cut tabs keep
   theirs. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--field);
  border-radius: var(--r-mount);
}

::selection {
  background: var(--laytr-mark);
  color: var(--on-mark);
}

h1,
h2,
h3,
h4,
p,
figure,
blockquote,
ul,
ol,
dl {
  margin: 0;
}

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

/* Skip link — visible the instant it is focused, never before. */
.skip {
  position: absolute;
  left: var(--s-l);
  top: var(--s-l);
  z-index: 100;
  padding: var(--s-m) var(--s-l);
  background: var(--ink);
  color: var(--field);
  font: 600 0.9375rem/1 var(--sans);
  border-radius: var(--r-mount);
  transform: translateY(-200%);
}

.skip:focus {
  transform: none;
}

/* -------------------------------------------------------------------------
   3. Type ramp

   The app's ramp maps to Dynamic Type. The web equivalent is a fluid ramp
   anchored to the same intent: display is the editorial voice, catalog is
   mono garnish that never grows past caption size.
   ------------------------------------------------------------------------- */

.display {
  font-size: clamp(2.75rem, 1.2rem + 6.6vw, 6.5rem);
  font-weight: 900;
  line-height: 0.94;
  letter-spacing: -0.035em;
  margin: 0;
}

.title {
  font-size: clamp(1.75rem, 1.1rem + 2.4vw, 3rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.025em;
}

.headline {
  font-size: clamp(1.1875rem, 1.05rem + 0.6vw, 1.5rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.012em;
}

.body {
  font-size: 1.0625rem;
  line-height: 1.6;
}

.lede {
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
  line-height: 1.5;
  letter-spacing: -0.005em;
}

.footnote {
  font-size: 0.9375rem;
  line-height: 1.5;
}

.muted {
  color: var(--ink-muted);
}

/* The accession line. Uppercase mono, +0.8 tracking, caption size, one line.
   Always garnish -- never load-bearing copy. */
.catalog {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.catalog--strong {
  font-weight: 700;
  color: var(--ink);
}

.catalog__sep {
  opacity: 0.55;
  padding: 0 0.35em;
}

/* Oversized thin numerals behind sections. Decorative texture, hidden from
   assistive technology, exactly like SerialNumeral in the app. */
.serial {
  position: absolute;
  right: 0;
  top: -0.28em;
  font-family: var(--sans);
  font-size: clamp(5rem, 14vw, 11rem);
  font-weight: 200;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--rule);
  pointer-events: none;
  user-select: none;
  /* Behind everything in the section, including content that is not itself
     positioned. Decoration must never paint over an exhibit. */
  z-index: -1;
}

/* -------------------------------------------------------------------------
   4. The reference mark
   ------------------------------------------------------------------------- */

.mark {
  display: inline-block;
  width: 0.72em;
  height: 0.72em;
  vertical-align: 0.12em;
  color: var(--laytr-mark);
  flex: none;
}

/* The masters carry their own width/height attributes; inside a .mark the
   box is the authority. */
.mark svg {
  display: block;
  width: 100%;
  height: 100%;
}

.mark--lg {
  display: block;
  width: clamp(3rem, 8vw, 5.5rem);
  height: clamp(3rem, 8vw, 5.5rem);
}

.center .mark--lg {
  margin-inline: auto;
}

/* -------------------------------------------------------------------------
   5. Layout
   ------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--page-margin);
}

@media (min-width: 48rem) {
  :root {
    --page-margin: 40px;
  }
}

.section {
  position: relative;
  padding-block: clamp(var(--s-xxl), 7vw, 96px);
}

/* Full-bleed hairline: the system's skeleton. */
.section + .section {
  border-top: var(--hairline) solid var(--rule);
}

.section__label {
  position: relative;
  z-index: 1;
  display: block;
  margin-bottom: var(--s-xl);
}

.stack > * + * {
  margin-top: var(--s-l);
}

.stack--tight > * + * {
  margin-top: var(--s-s);
}

.stack--loose > * + * {
  margin-top: var(--s-xl);
}

.measure {
  max-width: var(--measure);
}

.grid {
  display: grid;
  gap: var(--s-xl);
}

@media (min-width: 46rem) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }

  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* -------------------------------------------------------------------------
   6. Header and footer
   ------------------------------------------------------------------------- */

.masthead {
  border-bottom: var(--hairline) solid var(--rule);
}

.masthead__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-l);
  min-height: 64px;
  padding-block: var(--s-m);
}

.wordmark {
  display: block;
  color: var(--ink);
}

.wordmark svg,
.wordmark img {
  height: 26px;
  width: auto;
}

.masthead .wordmark {
  line-height: 0;
}

.nav ul {
  display: flex;
  align-items: center;
  gap: var(--s-l);
  flex-wrap: wrap;
}

.nav__link {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-muted);
  padding: var(--s-m) 0;
  display: inline-block;
}

.nav__link:hover {
  color: var(--ink);
}

.nav__link[aria-current="page"] {
  color: var(--ink);
  box-shadow: inset 0 -2px 0 0 var(--laytr-mark);
}

.colophon {
  border-top: var(--hairline) solid var(--rule);
  padding-block: var(--s-xxl) var(--s-xl);
}

.colophon__grid {
  display: grid;
  gap: var(--s-xl);
}

@media (min-width: 46rem) {
  .colophon__grid {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}

.colophon__links li + li {
  margin-top: var(--s-s);
}

.colophon__links a {
  text-decoration: none;
  font-size: 0.9375rem;
}

.colophon__links a:hover {
  text-decoration: underline;
  text-decoration-color: var(--laytr-mark);
}

.colophon__fine {
  margin-top: var(--s-xxl);
  padding-top: var(--s-l);
  border-top: var(--hairline) solid var(--rule);
}

.colophon__fine p + p {
  margin-top: var(--s-s);
}

/* -------------------------------------------------------------------------
   7. Mounts — the one card container
   ------------------------------------------------------------------------- */

.mount {
  background: var(--plinth);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-mount);
  padding: var(--s-xl);
}

.mount--flush {
  padding: 0;
  overflow: hidden;
}

.mount--field {
  background: var(--field);
}

/* -------------------------------------------------------------------------
   8. Index tabs — die-cut file dividers
   ------------------------------------------------------------------------- */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-s);
}

.tab {
  --tab-bg: var(--plinth);
  --tab-fg: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: var(--s-xs);
  min-height: 44px;
  padding: var(--s-s) var(--s-l);
  background: var(--tab-bg);
  color: var(--tab-fg);
  border: var(--hairline) solid var(--rule);
  border-bottom: none;
  border-radius: var(--r-mount) var(--r-mount) 0 0;
  clip-path: polygon(0 100%, 6px 0, calc(100% - 6px) 0, 100% 100%);
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.tab--selected,
.tab[aria-current="true"] {
  --tab-bg: var(--laytr-mark);
  --tab-fg: var(--on-mark);
  border-color: var(--laytr-mark);
}

.tabs__rule {
  height: var(--hairline);
  background: var(--rule);
  margin-top: -1px;
}

/* -------------------------------------------------------------------------
   9. Sticker chips

   The one place a shadow exists: a hard, unblurred 1.5x2 offset. It is a
   die-cut printed artefact, not elevation (DESIGN_SYSTEM §4).
   ------------------------------------------------------------------------- */

.stickers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-m);
}

.sticker {
  display: inline-flex;
  align-items: center;
  gap: var(--s-xs);
  padding: 6px var(--s-m);
  background: var(--plinth);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  box-shadow: 1.5px 2px 0 0 #000;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ±1° maximum static tilt, alternating across a row. */
.stickers .sticker:nth-child(odd) {
  transform: rotate(-1deg);
}

.stickers .sticker:nth-child(even) {
  transform: rotate(1deg);
}

.sticker--scheduled {
  background: var(--laytr-mark);
  color: var(--on-mark);
}

.sticker--due {
  background: var(--signal);
  color: var(--on-signal);
  border-color: var(--signal);
}

/* -------------------------------------------------------------------------
   10. Buttons — the only styled control, in two palette emphases
   ------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-s);
  min-height: 48px;
  padding: var(--s-m) var(--s-xl);
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: var(--plinth);
  color: var(--ink);
  font: 700 1.0625rem/1.2 var(--sans);
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: opacity 120ms linear;
}

/* The brand clicks, it does not wobble: the press is a flat opacity dip, so
   there is nothing for Reduce Motion to reduce. */
.btn:active {
  opacity: 0.62;
}

.btn--mark {
  background: var(--laytr-mark);
  color: var(--on-mark);
  border-color: var(--laytr-mark);
}

.btn--outline {
  background: var(--plinth);
  color: var(--ink);
}

.btn[aria-disabled="true"] {
  cursor: default;
  opacity: 1;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-m);
}

/* -------------------------------------------------------------------------
   11. Hero
   ------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(var(--s-xxl), 7vw, 88px) clamp(var(--s-xxl), 6vw, 72px);
}

.hero__mark {
  color: var(--laytr-mark);
  margin-bottom: var(--s-l);
}

.hero__display {
  max-width: 15ch;
}

.hero__lede {
  margin-top: var(--s-xl);
  max-width: 30rem;
}

.hero__actions {
  margin-top: var(--s-xl);
}

.hero__facts {
  margin-top: var(--s-xl);
  padding-top: var(--s-l);
  border-top: var(--hairline) solid var(--rule);
}

/* -------------------------------------------------------------------------
   12. Exhibits — release captures on flat mounts

   Presented as the app's own UI on a plinth, with no invented device chrome:
   Apple's marketing guidelines require Apple-provided bezels for device
   imagery, so the site shows no bezel at all rather than a lookalike.
   ------------------------------------------------------------------------- */

.exhibits {
  display: grid;
  gap: clamp(var(--s-xl), 4vw, 56px);
}

@media (min-width: 40rem) {
  .exhibits {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64rem) {
  .exhibits {
    grid-template-columns: repeat(3, 1fr);
  }
}

.exhibit {
  display: flex;
  flex-direction: column;
  gap: var(--s-m);
}

.exhibit__mount {
  background: var(--plinth);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-mount);
  padding: var(--s-m);
}

.exhibit__mount img {
  width: 100%;
  height: auto;
  border-radius: var(--r-thumb);
  opacity: var(--exhibit-strength);
}

.exhibit__title {
  margin-top: var(--s-xs);
}

/* At accessibility text sizes the editorial grid degrades to one column,
   the same rule the app's LazyVGrid follows at AX1+. */
@media (min-width: 40rem) {
  .exhibits--wide {
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  }
}

/* -------------------------------------------------------------------------
   13. The return ledger

   Mirrors the Later surface: named moments, each showing the concrete time it
   resolves to. Server-rendered with sensible text; ledger.js replaces the
   times with the visitor's own clock, which is the product's actual promise.
   ------------------------------------------------------------------------- */

.ledger {
  border-top: var(--hairline) solid var(--rule);
}

.ledger__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-l);
  padding-block: var(--s-l);
  border-bottom: var(--hairline) solid var(--rule);
}

.ledger__name {
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

/* The resolved time is load-bearing: a person reads it to decide whether the
   contract is real. Body voice, ink, never muted micro-mono (DESIGN_SYSTEM §3). */
.ledger__when {
  font-size: 1.0625rem;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.ledger__when .mark {
  margin-right: 0.35em;
}

/* -------------------------------------------------------------------------
   14. Plans
   ------------------------------------------------------------------------- */

.plans {
  display: grid;
  gap: var(--s-l);
}

@media (min-width: 46rem) {
  .plans {
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  }
}

.plan {
  display: flex;
  flex-direction: column;
  gap: var(--s-s);
  background: var(--plinth);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-mount);
  padding: var(--s-xl);
}

.plan__price {
  font-size: clamp(1.75rem, 1.4rem + 1.4vw, 2.375rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1;
}

.plan__period {
  color: var(--ink-muted);
  font-size: 0.9375rem;
}

/* The "best value" badge is a plinth sticker, never a second accent: only one
   thing per viewport wears full chartreuse. */
.plan__badge {
  align-self: flex-start;
  margin-bottom: var(--s-xs);
}

.plan__note {
  margin-top: auto;
  padding-top: var(--s-m);
  font-size: 0.9375rem;
  color: var(--ink-muted);
}

/* -------------------------------------------------------------------------
   15. Comparison table — hairlines and a catalog header row
   ------------------------------------------------------------------------- */

.compare {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.compare caption {
  text-align: left;
  margin-bottom: var(--s-m);
}

.compare th,
.compare td {
  padding: var(--s-m) var(--s-s);
  border-bottom: var(--hairline) solid var(--rule);
  vertical-align: top;
}

.compare thead th {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.compare tbody th {
  font-weight: 400;
  font-size: 1.0625rem;
}

.compare td {
  font-size: 1.0625rem;
}

.compare th:first-child,
.compare td:first-child {
  padding-left: 0;
}

/* -------------------------------------------------------------------------
   16. Prose — legal and support pages
   ------------------------------------------------------------------------- */

.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-top: var(--s-l);
}

.prose h2 {
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: var(--s-xxl);
  padding-top: var(--s-xl);
  border-top: var(--hairline) solid var(--rule);
}

.prose h3 {
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-top: var(--s-xl);
}

.prose ul {
  list-style: none;
  padding-left: 0;
}

.prose ul > li {
  position: relative;
  padding-left: 1.6em;
}

.prose ul > li + li {
  margin-top: var(--s-s);
}

/* Bulleted with the reference mark, the app's own bullet. */
.prose ul > li::before {
  content: "✳";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--laytr-mark);
  font-size: 0.85em;
  line-height: 1.75;
}

.prose ol {
  list-style: decimal;
  padding-left: 1.4em;
}

.prose ol > li + li {
  margin-top: var(--s-s);
}

.prose dt {
  font-weight: 700;
  margin-top: var(--s-l);
}

.prose a {
  text-decoration-color: var(--laytr-mark);
}

.prose strong {
  font-weight: 700;
}

.prose blockquote {
  border-left: 2px solid var(--laytr-mark);
  padding-left: var(--s-l);
  font-family: var(--serif);
  font-size: 1.125rem;
}

/* -------------------------------------------------------------------------
   17. Notes and callouts
   ------------------------------------------------------------------------- */

.note {
  background: var(--plinth);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-mount);
  padding: var(--s-l);
}

.note > * + * {
  margin-top: var(--s-s);
}

/* -------------------------------------------------------------------------
   18. Utilities
   ------------------------------------------------------------------------- */

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

.center {
  text-align: center;
}

.rule {
  height: var(--hairline);
  background: var(--rule);
  border: 0;
  margin: 0;
}

.relative {
  position: relative;
}

.z1 {
  position: relative;
  z-index: 1;
}

/* Long content that cannot reflow scrolls inside itself; the page body never
   scrolls sideways. */
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

@media print {
  .masthead nav,
  .hero__actions,
  .skip {
    display: none;
  }

  body {
    background: #fff;
    color: #000;
  }
}
