/* seed:managed sha256:{{SEED_SHA}} */
/* GENERATED by scripts/design/build_design.py from
   reference/design/tokens.yaml in the Cinova workspace.
   Do not edit. Change the canon and rebuild, or the surfaces drift
   apart again, which is the whole reason this file is generated. */

/* The page vocabulary: what a Cinova web page is made of.

   WHY IT IS SEPARATE FROM components.css
   That file is the app layer: controls, surfaces, a phone frame. It is what a
   portal is built from and it has no opinion about a page, because a portal is
   not a page. This is the other half: nav, hero, section, measure, grid,
   statement, footer. A marketing page, a web proposal and a case study are all
   built from these, exactly as every document is built from the .doc-* set.

   THE SAME REASONING AS PAPER, WITH THE TWO THINGS PAPER CANNOT HAVE
   Same face, same curve, same four weights, same radius scale, same emphasis
   rule: one element on a screenful inverts and there is no accent colour. What
   a screen adds is material, which lives on chrome and never on content, and
   motion, which belongs to anything a person can grab.

   No literal colour and no literal duration: guard_no_literals refuses both.
   Every font-size here gets its tracking attached mechanically by
   apply_curve_css, so a size cannot exist without the tracking that belongs
   to it. */

/* ─── TYPE ROLES ────────────────────────────────────────────────────────────
   Nine, and a page picks one. The document has fourteen because paper needs a
   running head and a table cell that a page does not; a page needs a hero size
   that paper has no room for. Both read the same scale. */
.t-display  { font-family: var(--font-display); letter-spacing: -0.0090em; line-height: 1.0630; font-size: 64px; font-weight: 600; }
.t-headline { font-family: var(--font-display); letter-spacing: -0.0030em; line-height: 1.0830; font-size: 48px; font-weight: 600; }
.t-title    { font-family: var(--font-display); letter-spacing: 0.0040em; line-height: 1.1250; font-size: 32px; font-weight: 600; }
.t-subtitle { font-family: var(--font-display); letter-spacing: 0.0090em; line-height: 1.1670; font-size: 24px; font-weight: 600; }
.t-data     { font-family: var(--font-display); letter-spacing: 0.0000em; line-height: 1.1000; font-size: 40px; font-weight: 600; font-variant-numeric: tabular-nums; }
.t-lede     { font-family: var(--font-display); letter-spacing: 0.0120em; line-height: 1.4210; font-size: 19px; font-weight: 400; }
.t-body     { font-family: var(--font-sans); letter-spacing: -0.0200em; line-height: 1.2500; font-size: 16px; font-weight: 400; }
.t-caption  { font-family: var(--font-sans); letter-spacing: -0.0160em; line-height: 1.2860; font-size: 14px; font-weight: 400; }
.t-label {
  font-family: var(--font-sans); line-height: 1.3330; font-size: 12px; font-weight: 400;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

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

/* ─── SHELL ─────────────────────────────────────────────────────────────── */
/* Border-box everywhere, or .wrap's width plus its gutter pans every phone:
   at 390px a content-box .wrap measures 438 wide. Same reset as the document
   and the gallery carry. Geometry only, so the literal guard is unaffected. */
*, *::before, *::after { box-sizing: border-box; }
h1, h2, h3, h4, h5, h6, p { margin: 0; }
img, video { max-width: 100%; height: auto; }
button, a { -webkit-tap-highlight-color: transparent; }

/* The sideways-pan safety net lives on html only. Never on body: on iOS
   Safari and in-app webviews body overflow-x detaches every fixed element,
   and no desktop engine reproduces it. */
html { overflow-x: clip; }
body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  font-optical-sizing: auto;
}

/* One gutter, set once, so nothing can scroll sideways on a phone. */
.wrap {
  width: 100%;
  max-width: 1120px;
  margin-inline: auto;
  padding-inline: 24px;
}

/* ─── NAV ───────────────────────────────────────────────────────────────────
   Content scrolls UNDER it, and the edge is a fade rather than a divider: a
   1px border under a sticky header draws a line whether or not anything is
   behind it. .chrome in components.css owns the material and the fade; this
   owns the layout only. */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--chrome-h-header);
  display: flex;
  align-items: center;
}
.nav .wrap { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.nav img { height: 17px; width: auto; display: block; }
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-links a { color: var(--ink-muted); text-decoration: none; }
.nav-links a[aria-current] { color: var(--ink); }

/* A phone keeps the one-row bar: tighter gaps under 700px so three links
   and the mark still fit a 360px viewport instead of panning it. */
@media (max-width: 700px) {
  .nav .wrap { gap: 12px; }
  .nav-links { gap: 16px; min-width: 0; }
}

/* Slide-Over narrow: the links may wrap to a second line rather than pan
   the page. One more link later must not reopen this fault. */
@media (max-width: 380px) {
  .nav .wrap { gap: 10px; }
  .nav-links { gap: 12px; flex-wrap: wrap; justify-content: flex-end; row-gap: 2px; }
}

/* ─── SECTIONS ──────────────────────────────────────────────────────────────
   One rhythm down the page. A section head is an eyebrow, a title and at most
   one sentence; if it needs two, the second one is the first paragraph. */
.section { padding-block: 96px; }
.section + .section { padding-top: 0; }
.section-head { display: grid; gap: 14px; max-width: 46ch; }
.section-body { margin-top: 44px; }

.hero { padding-block: 120px 96px; }
.hero-head { display: grid; gap: 22px; max-width: 900px; }
.hero .t-lede { max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; margin-top: 34px; }

/* Prose sits this side of 74 characters, because a longer line loses the
   reader on the way back to the left edge. */
.measure { max-width: 68ch; display: grid; gap: 18px; }

.rule { border: 0; border-top: 1px solid var(--line); }

/* ─── GRIDS ─────────────────────────────────────────────────────────────────
   They collapse to one column under 900px. A two-column grid with no
   responsive override is the single most common way a page pans sideways on a
   phone, and it is invisible on a desktop. */
.grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

/* A grid child defaults to min-width:auto, so one long word or wide table
   forces its track wider than the phone. Shrinkable children must go to
   zero, and prose must break rather than push. */
.grid > *, .statrow > *, .foot-grid > *, .measure > *,
.section-head > *, .section-body > *, .hero-head > * { min-width: 0; }
.t-display, .t-headline, .t-title, .t-subtitle, .t-data, .t-lede, .t-body, .t-caption {
  overflow-wrap: break-word;
}

/* A feature is a hairline box, not a shadowed one. Weight comes from the
   border and the contrast; a soft shadow on every card is the generated-app
   tell (anti-generic-design.md). */
.feature {
  background: var(--canvas-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 24px;
  display: grid;
  gap: 10px;
  align-content: start;
}
.feature svg { width: 20px; height: 20px; color: var(--ink-muted); }

/* ONE element on a screenful may invert, and that is the whole accent system.
   It is declared last in this file for the same reason the document's is:
   emphasis has to beat every component or it is not emphasis. */

/* ─── DATA ──────────────────────────────────────────────────────────────── */
.statrow { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 18px; }
@media (max-width: 900px) { .statrow { grid-auto-flow: row; } }
.stat-cell { display: grid; gap: 6px; align-content: start; }

/* ─── STATEMENT ─────────────────────────────────────────────────────────────
   A rule and a size change, the same as the document's pull quote. Never a
   giant quote mark and never a tinted box. */
.statement { border-left: 2px solid var(--ink); padding-left: 22px; max-width: 56ch; display: grid; gap: 12px; }

/* ─── CTA ───────────────────────────────────────────────────────────────── */
.cta {
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: 56px 44px;
  display: grid;
  gap: 18px;
  justify-items: start;
  background: var(--canvas-raised);
}
@media (max-width: 700px) { .cta { padding: 36px 24px; } }

/* ─── FOOTER ────────────────────────────────────────────────────────────────
   The page's back cover: the slogan, then the two people you can call. A
   footer that is only a slogan leaves a reader with nobody to ring. */
.foot { padding-block: 72px; border-top: 1px solid var(--line); margin-top: 96px; }
.foot-slogan { margin-bottom: 56px; white-space: nowrap; }
.foot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; max-width: 640px; }
@media (max-width: 700px) { .foot-grid { grid-template-columns: 1fr; } }
.foot-person { display: grid; gap: 4px; align-content: start; }
.foot-line { display: flex; align-items: center; gap: 8px; color: var(--ink-muted); text-decoration: none; }
.foot-line svg { width: 13px; height: 13px; flex: none; opacity: 0.6; }
.foot-legal { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; margin-top: 56px; color: var(--ink-dim); }

/* ─── EMPHASIS, LAST ────────────────────────────────────────────────────────
   Value, never hue, and one per screenful. Declared after every component
   above so it beats each of them on source order; putting it earlier is how an
   inverted card ends up as pale text on a pale ground and reads as a rendering
   fault rather than a cascade one. */
.invert, .invert.feature, .invert.cta {
  background: var(--feature);
  color: var(--feature-on);
  border-color: transparent;
}
.invert .muted, .invert .dim { color: var(--feature-on); opacity: 0.62; }
.invert svg { color: var(--feature-on); }

/* Responsive roles always receive their own curve-derived tracking and leading. */
@media (max-width: 700px) {
  .t-display { letter-spacing: 0.0000em; line-height: 1.1000; font-size: 40px; }
  .t-headline { letter-spacing: 0.0040em; line-height: 1.1250; font-size: 32px; }
  .foot-slogan { letter-spacing: 0.0070em; line-height: 1.1430; font-size: 28px; }
  .hero { padding-block: 64px; }
  .section { padding-block: 64px; }
}
@media (max-width: 350px) { .foot-slogan { letter-spacing: 0.0090em; line-height: 1.1670; font-size: 24px; } }
.nav a, .foot-line { min-height: 44px; display: inline-flex; align-items: center; }
.nav-brand { flex: none; }
.nav-toggle { display: none; }
.mobile-nav { padding: 0; border: 0; margin: 0 0 0 auto; width: min(86vw, 400px); max-width: none; height: 100dvh; max-height: 100dvh; color: var(--ink); background: var(--material-sheet-bg); backdrop-filter: blur(var(--material-sheet-blur)); }
.mobile-nav::backdrop { background: var(--material-scrim-bg); backdrop-filter: blur(var(--material-chrome-blur)); }
.mobile-nav-inner { min-height: 100%; display: flex; flex-direction: column; padding: 24px; padding-bottom: max(24px, env(safe-area-inset-bottom)); }
.mobile-close { align-self: end; }
.mobile-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-block: 32px; }
.mobile-links a { min-height: 44px; color: var(--ink); overflow-wrap: anywhere; }
.mobile-foot { margin-top: auto; }
@keyframes page-menu-row { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.mobile-nav[open] .mobile-links a { animation: page-menu-row var(--dur-menu) var(--ease-out) both; animation-delay: calc(var(--i) * var(--dur-press)); }
@media (max-width: 700px) { .nav-links { display: none; } .nav-toggle { display: inline-flex; } }
@media (prefers-reduced-motion: reduce) { .mobile-nav[open] .mobile-links a { animation: none; } }
.btn { transition: none; min-height: 44px; text-decoration: none; }
@keyframes page-menu-sheet { from { transform: translateX(100%); } to { transform: none; } }
.mobile-nav[open] { animation: page-menu-sheet var(--dur-sheet) var(--ease-sheet); }
@media (prefers-reduced-motion: reduce) { .mobile-nav[open] { animation: none; } }

/* Page controls use the same measured leading as page text. The app layer
   retains its own control layout; target_page derives these two roles. */
.btn { letter-spacing: -0.0180em; line-height: 1.2680; font-size: 15px; }
.btn-lg, .btn-block { letter-spacing: -0.0220em; line-height: 1.2350; font-size: 17px; }

/* A quiet section boundary using the same canvas roles in either appearance. */
.section-fade {
  background: linear-gradient(to bottom, var(--canvas-raised), var(--canvas) 240px);
  border-top: 1px solid var(--line);
}
