/*
  Design tokens: every value in docs/design/tokens.md as a CSS variable on :root, light first and the
  dark column under prefers-color-scheme. Components read these and nothing else; a new value goes in
  tokens.md first and here second.
*/
:root {
  color-scheme: light dark;

  /* Color */
  --canvas: #f3f2ee;
  --surface: #ffffff;
  --ink: #15171a;
  --ink-on-primary: #ffffff;
  --muted: #60656c;
  --tertiary: #a3a6ab;
  --line: #e4e3de;
  --field-edge: #84878c;
  --accent: #2457d6;
  --accent-soft: #e8eefc;
  --tint-identity: #e7dff5;
  --tint-confirm: #dde8e0;
  --status-overdue: #b24b40;
  --status-overdue-soft: #fbeae7;
  --status-attention: #916213;
  --status-attention-soft: #fbf1dc;
  --status-good: #26765d;
  --status-good-soft: #e3f0e8;
  --scrim: rgba(21, 23, 26, 0.32);

  /* Type: the web console's five sizes, 12 / 14 / 17 / 22 / 28 (tokens.md, decided 2026-10-25): 13 and 15 are not used. */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Inter, system-ui, sans-serif;
  --font-serif: "Fraunces", ui-serif, "New York", Georgia, serif;
  --type-display: 28px;
  --type-display-max: 28px;
  --type-title: 22px;
  --type-section: 14px;
  --type-eyebrow: 12px;
  --type-body: 17px;
  --type-secondary: 14px;
  --type-footnote: 14px;
  --leading-display: 34px;
  --leading-title: 28px;
  --leading-section: 20px;
  --leading-eyebrow: 16px;
  --leading-body: 22px;
  --leading-secondary: 20px;
  --leading-footnote: 20px;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --tracking-display: -0.02em;
  --tracking-eyebrow: 0.08em;

  /* Shape and space: the 4pt grid. */
  --radius-card: 16px;
  --radius-control: 12px;
  --radius-pill: 999px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --tap-min: 44px;
  --tap-capture: 64px;
  --tap-camera: 88px;
  --bar-primary: 56px;
  --shadow: none;
  --border-card: 1px solid var(--line);

  /* Kit metrics that tokens.md fixes in words. */
  --thumb-size: 56px;
  --thumb-radius: 12px;
  --row-height: 56px;
  --banner-min-height: 36px;
  --sidebar-width: 232px;
  --topbar-height: 44px;
  --panel-width: 480px;

  /* Motion: 150 to 250ms ease-out on sheets and list changes only. */
  --motion-fast: 150ms;
  --motion-slow: 250ms;
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #121212;
    --surface: #1c1c1e;
    --ink: #f2f2f2;
    --ink-on-primary: #121212;
    --muted: #a1a1aa;
    --tertiary: #6e7075;
    --line: #2c2c2e;
    --field-edge: #76787d;
    --accent: #7aa2ff;
    --accent-soft: #1b2a4a;
    --tint-identity: #2a2438;
    --tint-confirm: #1f2a22;
    --status-overdue: #ff8a7a;
    --status-overdue-soft: #3a1f1b;
    --status-attention: #f2c06b;
    --status-attention-soft: #3a2e12;
    --status-good: #7fd1ae;
    --status-good-soft: #15302a;
  }
}

/*
  The marketing site (docs/specs/site.md). The built stylesheet is the console's tokens.css followed by this file and
  motion.css (apps/site/build.mjs), so every value here is a token. The values the console does not have, the site's
  Hero, Headline, Row title and Figure sizes, are tokens.md's marketing rows and live here because only the site uses
  them. The layout follows the founder's reference, Figma's web-development page: large regular headlines, 120px
  between sections, text beside its picture, hairlines for structure. A name in double braces is an asset the build
  renames with its hash.
*/
@font-face {
  font-family: "Fraunces";
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url("fraunces-500.7975c1ef7c.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url("fraunces-600.3a1de7711d.woff2") format("woff2");
}

/* tokens.md, marketing rows: phone first, then 768 and 1024 wide. */
:root {
  --type-hero: 36px;
  --leading-hero: 40px;
  --type-headline: 28px;
  --leading-headline: 34px;
  --type-row: 22px;
  --leading-row: 28px;
  --type-figure: 64px;
  --leading-figure: 64px;
  --gutter: var(--space-4);
  --band: 64px;
  --gap: var(--space-6);
  /* The mat around a screenshot: padding and the 1px edge. */
  --mat: calc(var(--space-4) + 1px);
}
@media (min-width: 600px) {
  :root {
    --gutter: var(--space-5);
  }
}
@media (min-width: 768px) {
  :root {
    --type-hero: 48px;
    --leading-hero: 52px;
    --type-headline: 36px;
    --leading-headline: 40px;
    --type-figure: 96px;
    --leading-figure: 96px;
    --band: 96px;
    --gap: 48px;
  }
}
@media (min-width: 1024px) {
  :root {
    --type-hero: 64px;
    --leading-hero: 68px;
    --type-headline: 48px;
    --leading-headline: 52px;
    --type-row: 28px;
    --leading-row: 34px;
    --type-figure: 128px;
    --leading-figure: 128px;
    --band: 120px;
    --gap: 64px;
  }
}

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

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ol, figure {
  margin: 0;
}
/* Headings wrap in even lines, so a heading never ends on a one-word stub; running text avoids a lone last word. */
h1, h2, h3 {
  text-wrap: balance;
}
p {
  text-wrap: pretty;
}

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

img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Read by a screen reader, not shown. */
.hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The console's focus ring (apps/console/src/styles/base.css). */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

/* One column of up to 1280px between the gutters. */
.wrap {
  width: 100%;
  max-width: 1328px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* A hairline across the whole width marks the top of the page, as on the reference. */
.masthead {
  border-bottom: 1px solid var(--line);
}
.masthead .wrap {
  padding-block: var(--space-5);
}

/* A wordmark, not a heading and not a link: the page is the whole site. */
.wordmark {
  font-family: var(--font-serif);
  font-weight: var(--weight-semibold);
  font-size: var(--type-title);
  line-height: var(--leading-title);
}

.hero {
  padding-top: var(--band);
}

/* The page's one serif sentence (principles rule 1), tracked tight like every display line (rule 17). */
.hero-title {
  max-width: 1000px;
  font-family: var(--font-serif);
  font-weight: var(--weight-medium);
  font-size: var(--type-hero);
  line-height: var(--leading-hero);
  letter-spacing: var(--tracking-display);
}

.lede {
  max-width: 680px;
  margin-top: var(--space-5);
  color: var(--muted);
}
@media (min-width: 768px) {
  .lede {
    font-size: var(--type-title);
    line-height: var(--leading-title);
  }
}

.action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* The console's PrimaryActionButton as a link: ink fill, white label, the trailing arrow. */
.primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--bar-primary);
  padding-inline: var(--space-5);
  border-radius: var(--radius-control);
  background: var(--ink);
  color: var(--ink-on-primary);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}
/* A press lifts the ink one step toward the surface: a state change, no motion (tokens.md, Press states). */
.primary:active {
  background: color-mix(in srgb, var(--ink) 80%, var(--surface));
}

.arrow {
  flex: none;
}

.note {
  font-size: var(--type-secondary);
  line-height: var(--leading-secondary);
  color: var(--muted);
}

@media (max-width: 599px) {
  .action {
    align-items: stretch;
  }
  .primary {
    width: 100%;
  }
}

/*
  A screenshot sits on a surface mat inside the card's edge and radius. The console's canvas inside it then reads as a
  picture of the app, not as the page's own controls (the critic, 2026-10-27).
*/
/* clip, not hidden: hidden would make the mat a scroll container, and the outlines' view timelines would then track
   the mat instead of the window and never finish (motion.css). */
.shot {
  padding: var(--space-4);
  overflow: clip;
  border: var(--border-card);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.shot img {
  width: 100%;
}
.shot-hero {
  margin-top: var(--gap);
}
/* On a phone a shot shown at nearly its own size reads as live controls, so it sits narrower, as a picture. */
@media (max-width: 599px) {
  .shot {
    width: 100%;
    max-width: 320px;
    margin-inline: auto;
  }
}

/* The close-up: two overdue rows, with what each part of a row tells the manager. */
.closeup {
  margin-top: var(--space-6);
}
.closeup-frame {
  position: relative;
}
.closeup-labels {
  margin-bottom: var(--space-3);
}
.closeup-label {
  font-size: var(--type-section);
  line-height: var(--leading-section);
  font-weight: var(--weight-semibold);
}
/* Below 1200 wide the four labels read as one line of phrases, the middle dot between them silent. */
@media (max-width: 1199px) {
  .closeup-labels ol {
    display: flex;
    flex-wrap: wrap;
    column-gap: var(--space-2);
  }
  .closeup-label + .closeup-label::before {
    content: "·" / "";
    margin-right: var(--space-2);
    color: var(--muted);
  }
  .closeup-mark {
    display: none;
  }
}
/*
  From 1200 wide each label sits over its part of the strip, and a 2px ink outline marks that part. Positions are
  shares of the cut (build.mjs, rows-desktop): the Overdue group header, Waiting on, Follows up, Next check-in.
*/
@media (min-width: 1200px) {
  .closeup-labels {
    position: relative;
    height: var(--leading-section);
  }
  .closeup-label {
    position: absolute;
    top: 0;
    left: calc(var(--mat) + (100% - 2 * var(--mat)) * var(--at));
    white-space: nowrap;
  }
  .closeup-label:nth-child(1) { --at: 0.004; }
  .closeup-label:nth-child(2) { --at: 0.426; }
  .closeup-label:nth-child(3) { --at: 0.646; }
  .closeup-label:nth-child(4) { --at: 0.766; }

  .closeup-mark {
    position: absolute;
    border: 2px solid var(--ink);
    border-radius: var(--radius-control);
  }
  .closeup-mark:nth-of-type(1) { left: 0.4%; top: 4%; width: 8.3%; height: 17%; }
  .closeup-mark:nth-of-type(2) { left: 42.6%; top: 22%; width: 14.6%; height: 74%; }
  .closeup-mark:nth-of-type(3) { left: 64.6%; top: 22%; width: 6.2%; height: 74%; }
  .closeup-mark:nth-of-type(4) { left: 76.6%; top: 22%; width: 21.6%; height: 74%; }
}

.band {
  padding-top: var(--band);
}

/* Section titles: large and regular, tracked like display type (tokens.md, Headline). */
.headline {
  font-size: var(--type-headline);
  line-height: var(--leading-headline);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-display);
}

/* From 1024 wide a section sets its title in the left column and its content in the right. */
.split {
  display: grid;
  gap: var(--space-5);
}
@media (min-width: 1024px) {
  .split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--gap);
  }
}

/* About 70 characters a line at 17px. */
.prose {
  display: grid;
  gap: var(--space-4);
  max-width: 560px;
}

/*
  The one sourced figure, set large in the page's own sans with proportional digits (dataviz, hero figure), inside the
  argument it supports. Not a stat tile: rule 2 governs the working screens.
*/
.fact {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
}
.fact-n {
  display: block;
  margin-bottom: var(--space-3);
  font-size: var(--type-figure);
  line-height: var(--leading-figure);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-display);
}
@media (min-width: 768px) {
  .fact-line {
    font-size: var(--type-title);
    line-height: var(--leading-title);
  }
}
.fact-source {
  font-size: var(--type-secondary);
  line-height: var(--leading-secondary);
  color: var(--muted);
}

.intro .lede {
  margin-top: var(--space-4);
}

.rows {
  display: grid;
  gap: var(--band);
  margin-top: var(--gap);
}

/* A feature row: the words beside their picture from 1024 wide, above it below that. */
.row {
  display: grid;
  gap: var(--space-5);
}
@media (min-width: 1024px) {
  .row {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: center;
    gap: var(--gap);
  }
  /* A row's shot is a cut of the screen shown at about its own size, against the right edge, as on the reference. */
  .row .shot {
    justify-self: end;
    width: 100%;
    max-width: calc(var(--shot-width) + 2 * var(--mat));
  }
  .row:nth-child(1) .shot { --shot-width: 561px; }
  .row:nth-child(2) .shot { --shot-width: 780px; }
}

.row-title {
  font-size: var(--type-row);
  line-height: var(--leading-row);
  font-weight: var(--weight-regular);
}

.row-text p {
  max-width: 480px;
  margin-top: var(--space-3);
}

/* Answers as a list with hairlines between them. */
.qa {
  padding-block: var(--space-5);
  border-top: 1px solid var(--line);
}
.qa:last-child {
  border-bottom: 1px solid var(--line);
}
.qa h3 {
  font-size: var(--type-body);
  line-height: var(--leading-body);
  font-weight: var(--weight-semibold);
}
.qa p {
  max-width: 560px;
  margin-top: var(--space-2);
}

/*
  The pilot is a note from a person: the page's one tinted card, the identity lavender (rule 15), beside its title,
  with the founder named the way the console's IdentityCard names someone.
*/
.pilot {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6);
  border-radius: var(--radius-card);
  background: var(--tint-identity);
}
.pilot p {
  max-width: 560px;
}
.person {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.initials {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  font-size: var(--type-secondary);
  font-weight: var(--weight-semibold);
}
.person-text {
  display: flex;
  flex-direction: column;
}
.person-name {
  font-weight: var(--weight-semibold);
}
.person-role {
  font-size: var(--type-secondary);
  line-height: var(--leading-secondary);
  color: var(--muted);
}
.pilot .action {
  margin-top: 0;
}

.footer {
  margin-top: var(--band);
  border-top: 1px solid var(--line);
}
.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-5);
}

/* A plain link at the full tap height; pressed, it darkens toward the ink (tokens.md, Press states). */
.mail {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--accent);
  text-decoration: none;
}
.mail:hover {
  text-decoration: underline;
}
.mail:active {
  color: color-mix(in srgb, var(--accent) 70%, var(--ink));
}

/*
  The site's scroll motion (CLAUDE.md, "Website": the one exception to the motion rule, after the founder asked for an
  apple.com feel when scrolling down). Every effect runs on a CSS view timeline, so the browser drives it from the
  scroll position with no script and no scroll events, and only transform and opacity move (fixing-motion-performance).
  Where a browser has no view timelines, or the reader asks for reduced motion, none of this applies and the page is
  still. build.mjs appends this file after site.css. tools/site/shoot.mjs checks every block below settles in view;
  keep its MOVED list the same as these selectors.
*/
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* Each block fades up over its first 240px in view, whatever its height, so tall blocks never read half faded. */
    @keyframes site-rise {
      from {
        opacity: 0;
        transform: translateY(32px);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }

    /* The board rises and grows into place as the page scrolls toward it, as a product shot does on apple.com. */
    @keyframes site-settle {
      from {
        transform: translateY(48px) scale(0.92);
      }
      to {
        transform: none;
      }
    }

    /* The sourced figure grows from its baseline as it comes into view. */
    @keyframes site-figure {
      from {
        opacity: 0;
        transform: scale(0.8);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }

    /* A close-up label or outline appears where it points. */
    @keyframes site-appear {
      from {
        opacity: 0;
        transform: translateY(8px);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }

    /* Scaled from its top left, the board keeps its left edge on the text's edge while it grows. */
    .shot-hero {
      transform-origin: left top;
      animation: site-settle linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }

    .closeup-shot,
    .split > .headline,
    .split > .prose,
    .split > .answers > .qa,
    .split > .pilot,
    .intro > *,
    .row > * {
      animation: site-rise var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% entry 240px;
    }

    .fact-n {
      transform-origin: left bottom;
      animation: site-figure var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }

    /* Below 1200 the labels are one line of phrases and rise together. */
    @media (max-width: 1199px) {
      .closeup-labels {
        animation: site-rise var(--ease-out) both;
        animation-timeline: view();
        animation-range: entry 0% entry 240px;
      }
    }

    /* From 1200 each label and its outline appear in turn, 60px of scroll apart, left to right. */
    @media (min-width: 1200px) {
      .closeup-label,
      .closeup-mark {
        animation: site-appear var(--ease-out) both;
        animation-timeline: view();
      }
      .closeup-label:nth-child(1), .closeup-mark:nth-of-type(1) { animation-range: entry 0% entry 160px; }
      .closeup-label:nth-child(2), .closeup-mark:nth-of-type(2) { animation-range: entry 60px entry 220px; }
      .closeup-label:nth-child(3), .closeup-mark:nth-of-type(3) { animation-range: entry 120px entry 280px; }
      .closeup-label:nth-child(4), .closeup-mark:nth-of-type(4) { animation-range: entry 180px entry 340px; }
    }
  }
}
