/* TradeSmart Systems, v2. One stylesheet for every page. Engine: scrollcraft.css (unmodified). */

/* ---------------------------------------------------------------- fonts --
   Archivo and Geist, straight from Google's font files (the CSP's font-src), declared here so the
   page does not wait on a second stylesheet from another server before it can paint. The latin
   files are preloaded by the pages. Each family has a local stand-in sized to take the same room
   (size-adjust and the ascent/descent overrides, measured off the real files), so the swap to the
   web font moves nothing: Arial where it exists, Roboto on Android. */
@font-face { font-family: "Archivo"; font-style: normal; font-weight: 400 900; font-stretch: 62% 125%; font-display: swap;
  src: url(https://fonts.gstatic.com/s/archivo/v25/k3kQo8UDI-1M0wlSfdboLmvDIaK18A.woff2) format("woff2");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; }
@font-face { font-family: "Archivo"; font-style: normal; font-weight: 400 900; font-stretch: 62% 125%; font-display: swap;
  src: url(https://fonts.gstatic.com/s/archivo/v25/k3kQo8UDI-1M0wlSfdfoLmvDIaK18A.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Archivo"; font-style: normal; font-weight: 400 900; font-stretch: 62% 125%; font-display: swap;
  src: url(https://fonts.gstatic.com/s/archivo/v25/k3kQo8UDI-1M0wlSfdnoLmvDIaI.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Geist"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwRGFWNOITddY4.woff2) format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: "Geist"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwYGFWNOITddY4.woff2) format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Geist"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwTGFWNOITddY4.woff2) format("woff2");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; }
@font-face { font-family: "Geist"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwSGFWNOITddY4.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Geist"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwcGFWNOITd.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* the stand-ins: the display face is set heavy and wide, so it is matched against a bold face */
@font-face { font-family: "Archivo Fallback"; src: local("Arial Bold"), local("Arial-BoldMT");
  size-adjust: 110.3%; ascent-override: 79.6%; descent-override: 19.04%; line-gap-override: 0%; }
@font-face { font-family: "Archivo Fallback R"; src: local("Roboto Bold"), local("Roboto-Bold");
  size-adjust: 117.5%; ascent-override: 74.73%; descent-override: 17.87%; line-gap-override: 0%; }
@font-face { font-family: "Geist Fallback"; src: local("Arial"), local("ArialMT");
  size-adjust: 106.26%; ascent-override: 94.58%; descent-override: 27.76%; line-gap-override: 0%; }
@font-face { font-family: "Geist Fallback R"; src: local("Roboto"), local("Roboto-Regular");
  size-adjust: 105.39%; ascent-override: 95.36%; descent-override: 27.99%; line-gap-override: 0%; }

:root {
  --night: #0B0D10;
  --night-surface: #14171C;
  --night-raise: #1B1F26;
  --night-ink: #F2F0ED;
  --night-soft: #A7A3A0;
  --night-accent: #E0453C;
  --glow: #8B0000;
  --day: #F2F3F5;
  --day-surface: #FFFFFF;
  --day-ink: #121417;
  --day-soft: #4F5561;
  --day-accent: #8B0000;
  --brand: #8B0000;
  --steel: #C9CDD3;

  --sc-canvas: var(--night);
  --sc-surface: var(--night-surface);
  --sc-ink: var(--night-ink);
  --sc-ink-soft: var(--night-soft);
  --sc-accent: var(--night-accent);
  --sc-accent-ink: #0B0D10;
  --sc-font-display: "Archivo", "Archivo Fallback", "Archivo Fallback R", system-ui, sans-serif;
  --sc-font-text: "Geist", "Geist Fallback", "Geist Fallback R", system-ui, sans-serif;
  --sc-shadow-color: 220 30% 4%;
  --sc-maxw: 90rem;

  --bar-h: 68px;
  --wide: 116%;
  --r: 10px;
  --r-lg: 20px;
  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-io: cubic-bezier(0.77, 0, 0.175, 1);
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.075 0'/></filter><rect width='220' height='220' filter='url(%23g)'/></svg>");
  --noise: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.55 0'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
}
@media (max-width: 700px) {
  :root { --bar-h: 58px; --wide: 106%; }
}

/* One continuous dark ground for every page: matte black (no ribs, no sheen) with
   a fine grain. Dark sections are transparent over it, so one dark section flows into the next. */
body::before {
  content: ""; position: fixed; inset: -20vmax; z-index: -1; pointer-events: none;
  background: var(--night);
}
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--grain); background-size: 220px 220px;
}
/* The living background (site.js initBackground; html data-bg picks the direction, 6 when absent):
   ribbed glass in a light palette, multiplied over the light grounds only (white everywhere else).
   The dark ground has no glass: it is the matte CSS ground above. */
.bgfx { position: fixed; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.bgfx--night { z-index: -1; }
.bgfx--day { z-index: 50; mix-blend-mode: multiply; }

/* dark cards and panels sitting on a light ground carry their own soft light */
.menu__panel {
  --card-tex: radial-gradient(90% 80% at 88% 12%, rgba(120,138,168,0.12), transparent 72%), var(--grain);
}
body { background: var(--night); }

.ground-night {
  --sc-canvas: var(--night); --sc-surface: var(--night-surface);
  --sc-ink: var(--night-ink); --sc-ink-soft: var(--night-soft);
  --sc-accent: var(--night-accent); --sc-accent-ink: #0B0D10;
  --sc-shadow-color: 220 30% 4%;
  background-color: transparent;
  color: var(--sc-ink);
}
.ground-day {
  --sc-canvas: var(--day); --sc-surface: var(--day-surface);
  --sc-ink: var(--day-ink); --sc-ink-soft: var(--day-soft);
  --sc-accent: var(--day-accent); --sc-accent-ink: #FFFFFF;
  --sc-shadow-color: 220 18% 30%;
  background-color: var(--day);
  color: var(--sc-ink);
}
.grain { position: relative; isolation: isolate; }
.grain::after { content: none; }

.vh {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: fixed; left: 12px; top: 10px; z-index: 100;
  background: var(--night-ink); color: var(--night); padding: 10px 14px; border-radius: var(--r);
  transform: translateY(-160%); transition: transform 160ms var(--ease);
}
.skip:focus-visible { transform: none; }
:where([data-sc-stage]) { position: relative; }

.wrap { width: 100%; max-width: var(--sc-maxw); margin-inline: auto; padding-inline: var(--sc-gutter); }

.display {
  font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 720;
  line-height: 1.02; letter-spacing: -0.028em; text-wrap: balance; margin: 0;
}
.display--xl { font-size: clamp(2.7rem, 1.2rem + 5.4vw, 6.6rem); letter-spacing: -0.035em; }
.display--lg { font-size: clamp(2.3rem, 1.3rem + 3.6vw, 5rem); }
.display--md { font-size: clamp(1.9rem, 1.3rem + 2.2vw, 3.4rem); }
.lede {
  font-size: clamp(1.1rem, 0.98rem + 0.5vw, 1.4rem); line-height: 1.55; letter-spacing: -0.008em;
  color: var(--sc-ink-soft); text-wrap: pretty; max-width: 36em; margin: 0;
}
.label {
  display: inline-flex; align-items: center; gap: 10px; margin: 0;
  font-family: var(--sc-font-text); font-size: 0.82rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--sc-ink-soft);
}
.red { color: var(--sc-accent); }


/* ------------------------------------------------------------ buttons -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 50px; padding: 0 24px;
  font-family: var(--sc-font-display); font-stretch: 112%; font-weight: 650;
  font-size: 1rem; letter-spacing: 0.005em; white-space: nowrap;
  color: #FFFFFF; background: var(--brand);
  border-radius: var(--r); text-decoration: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 0 0 1px rgba(255,255,255,0.12), 0 8px 22px -8px rgba(139,0,0,0.75);
  transition: background-color 160ms var(--ease), box-shadow 160ms var(--ease), scale 120ms var(--ease);
}
.ground-day .btn, [data-ground="day"] .bar .btn {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 8px 18px -10px rgba(80,0,0,0.6);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: #A30E0E; }
  .textlink:hover { text-decoration-thickness: 2px; text-decoration-color: currentColor; }
}
.btn:active { scale: 0.98; }
.btn--bar { min-height: 40px; padding: 0 16px; font-size: 0.92rem; }
.btn--big { min-height: 58px; padding: 0 32px; font-size: 1.08rem; }

.textlink {
  color: var(--sc-ink); text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--sc-ink) 45%, transparent);
  text-underline-offset: 0.25em; text-decoration-thickness: 1px; font-size: 1rem;
}
.arrow::after { content: ""; display: inline-block; width: 0.6em; height: 0.6em; margin-left: 0.45em;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor; rotate: 45deg; translate: 0 -0.08em;
  transition: translate 180ms var(--ease); }
@media (hover: hover) and (pointer: fine) { a:hover > .arrow::after, .arrow:hover::after { translate: 0.2em -0.08em; } }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; margin-top: 30px; }

:focus-visible { outline-color: var(--sc-accent); }
.ground-day :focus-visible { outline-color: var(--day-accent); }

/* -------------------------------------------------- view transitions -- */
@view-transition { navigation: auto; }
.bar { view-transition-name: bar; }
.chat { view-transition-name: chat; }
::view-transition-old(root) { animation: vt-old 520ms var(--ease-io) both; }
::view-transition-new(root) { animation: vt-new 620ms var(--ease) both; }
@keyframes vt-old { to { opacity: 0.35; scale: 0.965; filter: brightness(0.7); } }
@keyframes vt-new { from { clip-path: inset(100% 0 0 0 round 28px 28px 0 0); translate: 0 8vh; } to { clip-path: inset(0 0 0 0 round 0); translate: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ------------------------------------------------------------------ bar -- */
.bar {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  height: var(--bar-h);
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding-inline: var(--sc-gutter);
  color: var(--night-ink);
  transition: background-color 260ms var(--ease), box-shadow 260ms var(--ease), color 260ms var(--ease);
}
.bar::before {
  content: ""; position: absolute; inset: 0 0 -44px 0; z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom, rgba(11,13,16,0.85), rgba(11,13,16,0.4) 55%, transparent);
  transition: opacity 260ms var(--ease);
}
.bar.is-scrolled {
  background: rgba(11,13,16,0.82);
  -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: 0 1px 0 rgba(242,240,237,0.07);
}
.bar.is-scrolled::before { opacity: 0; }
html:not(.js) .bar, .sc-failsafe .bar { position: absolute; }
.bar__brand { display: flex; align-items: center; height: 100%; text-decoration: none; border-radius: 6px; flex: 0 0 auto; }
/* Night: two crops of the locked chrome lockup (cut from the master, never redrawn): the mark,
   and the wordmark with SYSTEMS, each at its own scale so SYSTEMS can be read. Each crop is cut from the
   master at 8x the size the bar draws it (brand/make_bar_logo.py), so it stays sharp at any zoom or
   screen density; the ?v= stamp makes a browser fetch a new cut instead of keeping an old one. */
.lockup-chrome { display: inline-flex; align-items: center; gap: 13px; --ms: 0.124; --ws: 0.3; }
.lockup-chrome > span { display: block; flex: none; background-repeat: no-repeat; background-position: center; background-size: 100% 100%; }
.lockup-chrome__mark {
  width: calc(249.3px * var(--ms)); height: calc(300px * var(--ms));
  background-image: url("/assets/brand/ts-bar-mark@8x.webp?v=b73f582c1a");
}
.lockup-chrome__word {
  width: calc(521.6px * var(--ws)); height: calc(116px * var(--ws));
  background-image: url("/assets/brand/ts-bar-word@8x.webp?v=c2b5020778");
}
.lockup-day { display: none; align-items: center; gap: 13px; color: var(--day-ink); }
.lockup-day__mark { height: calc(var(--bar-h) - 34px); width: auto; }
.wordmark { display: inline-flex; flex-direction: column; align-items: center; line-height: 1; }
.wordmark__top {
  font-family: var(--sc-font-display); font-weight: 800; font-stretch: 92%;
  font-size: 1.42rem; letter-spacing: 0.01em; color: var(--day-ink);
}
.wordmark__red { color: var(--day-accent); }
.wordmark__sub {
  font-family: var(--sc-font-text); font-weight: 600; font-size: 0.62rem;
  letter-spacing: 0.62em; margin-right: -0.62em; margin-top: 4px; color: var(--day-soft);
}
.wordmark--small .wordmark__top { font-size: 1rem; }
.wordmark--small .wordmark__sub { font-size: 0.42rem; }

.nav { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 38px); margin-left: auto; }
.nav a {
  position: relative; padding: 8px 0; text-decoration: none; color: inherit;
  font-size: 0.95rem; font-weight: 500; letter-spacing: 0.005em; opacity: 0.86;
  transition: opacity 160ms var(--ease);
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 2px; height: 2px; border-radius: 2px;
  background: var(--night-accent); transform: scaleX(0); transform-origin: left;
  transition: transform 260ms var(--ease);
}
.nav a[aria-current="page"] { opacity: 1; }
.nav a[aria-current="page"]::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .nav a:hover { opacity: 1; }
  .nav a:hover::after { transform: scaleX(1); }
}
.nav a { white-space: nowrap; }
/* seven page links: tighter up to 1440 wide, and the Menu button instead of the row at 1120 wide and
   below (measured: the row, Get started and Client login need about 1120), so the row never runs
   under Get started or Client login and the bar never runs off the screen */
@media (min-width: 1121px) and (max-width: 1440px) {
  .nav { gap: clamp(12px, 1.3vw, 20px); }
  .nav a { font-size: 0.88rem; }
}
@media (min-width: 981px) and (max-width: 1120px) {
  .nav { display: none; }
  .bar .menu { display: block; }
}
.bar__end { display: flex; align-items: center; gap: 12px; }

/* the client portal door: a quiet outlined button on the far right, past a divider, not a page link */
.bar__sep { width: 1px; height: 24px; margin: 0 2px; background: color-mix(in oklab, currentColor 22%, transparent); flex: none; }
.btn-login {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; flex: none;
  min-height: 40px; padding: 0 14px; border-radius: var(--r); white-space: nowrap;
  font-family: var(--sc-font-display); font-stretch: 112%; font-weight: 600; font-size: 0.92rem; letter-spacing: 0.005em;
  color: inherit; background: transparent; border: 1px solid color-mix(in oklab, currentColor 38%, transparent); text-decoration: none;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease), color 160ms var(--ease);
}
.btn-login__ico { flex: none; }
.btn-login:hover, .btn-login:focus-visible { border-color: currentColor; background: color-mix(in oklab, currentColor 8%, transparent); }
.btn-login--menu { display: none; }
@media (min-width: 981px) and (max-width: 1180px) {
  .bar__end { gap: 8px; }
  .btn-login { padding: 0 11px; font-size: 0.86rem; gap: 6px; }
}

.menu { display: none; }
.menu > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 0 12px; border-radius: var(--r);
  font-size: 0.92rem; font-weight: 600; color: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, currentColor 28%, transparent);
}
.menu > summary::-webkit-details-marker { display: none; }
.menu__icon { width: 16px; height: 10px; position: relative; }
.menu__icon::before, .menu__icon::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform 220ms var(--ease), top 220ms var(--ease);
}
.menu__icon::before { top: 0; }
.menu__icon::after { top: 8px; }
.menu[open] .menu__icon::before { top: 4px; transform: rotate(45deg); }
.menu[open] .menu__icon::after { top: 4px; transform: rotate(-45deg); }
.menu__panel {
  position: fixed; left: 0; right: 0; top: var(--bar-h); z-index: 59;
  height: calc(100svh - var(--bar-h)); overflow-y: auto;
  padding: 28px var(--sc-gutter) 40px;
  background: var(--night); background-image: var(--card-tex); background-size: auto, 220px 220px; color: var(--night-ink);
  display: flex; flex-direction: column; gap: 6px;
}
.menu__panel a:not(.btn) {
  display: block; padding: 12px 0; text-decoration: none; color: inherit;
  font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 700;
  font-size: 2rem; letter-spacing: -0.02em;
  border-bottom: 1px solid rgba(242,240,237,0.1);
}
.menu__panel a[aria-current="page"] { color: var(--night-accent); }
.menu__panel .btn { margin-top: 24px; align-self: flex-start; }
.menu[open] .menu__panel { animation: menu-in 320ms var(--ease) both; }
@keyframes menu-in { from { opacity: 0; translate: 0 -12px; } to { opacity: 1; translate: 0 0; } }

[data-ground="day"] .bar {
  background: rgba(242,243,245,0.88);
  -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: 0 1px 0 rgba(18,20,23,0.08);
  color: var(--day-ink);
}
[data-ground="day"] .bar::before { opacity: 0; }
[data-ground="day"] .lockup-chrome { display: none; }
[data-ground="day"] .lockup-day { display: inline-flex; }
[data-ground="day"] .bar :focus-visible { outline-color: var(--day-accent); }
[data-ground="day"] .nav a::after { background: var(--day-accent); }

/* ------------------------------------------------------------ footer -- */
.foot { border-top: 1px solid color-mix(in oklab, var(--day-ink) 11%, transparent); }
.foot__in {
  display: grid; grid-template-columns: 1fr auto; gap: 28px 40px; align-items: start;
  padding-block: 44px 40px; padding-inline-end: max(var(--sc-gutter), 88px);
}
.foot__brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.foot__brand img { height: 30px; width: auto; }
.foot__nav { display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 0; padding: 0; list-style: none; }
.foot__nav a { color: var(--day-ink); text-decoration: none; font-size: 0.95rem; font-weight: 500; }
@media (hover: hover) and (pointer: fine) { .foot__nav a:hover { text-decoration: underline; text-underline-offset: 0.25em; } }
.foot__legal {
  grid-column: 1 / -1; margin: 0; display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: 0.88rem; color: var(--day-soft);
  padding-top: 22px; border-top: 1px solid color-mix(in oklab, var(--day-ink) 8%, transparent);
}
.foot__legal a { color: inherit; }

/* ---------------------------------------------- lines that assemble -- */
/* site.js wraps each rendered line of a [data-lines] element in a mask. Nothing is hidden
   until the split has happened, so no script means the plain heading. */
.ln { display: block; overflow: clip; overflow-clip-margin: 0.1em; padding-bottom: 0.12em; margin-bottom: -0.12em; }
.ln__i { display: inline-block; transition: transform 900ms var(--ease), opacity 900ms var(--ease); transition-delay: calc(var(--i, 0) * 90ms + var(--d, 0ms)); }
.js [data-lines].is-split:not(.is-lit) .ln__i { transform: translateY(108%); opacity: 0; }
.ch { display: inline-block; transition: transform 800ms var(--ease), opacity 800ms var(--ease); transition-delay: calc(var(--i, 0) * 38ms + 120ms); }
.js [data-chars].is-split:not(.is-lit) .ch { transform: translateY(0.45em); opacity: 0; }
.js .fade-up { transition: opacity 800ms var(--ease), transform 800ms var(--ease); transition-delay: var(--d, 0ms); }
.js .is-arriving .fade-up { opacity: 0; transform: translateY(16px); }

/* ------------------------------------------------------- copy blocks -- */
/* Prose that sits in a grid or flex layout lives in a copy block, the block being the layout item,
   so a paragraph added in the editor stacks under the one before it instead of taking another cell.
   A second paragraph gets the spacing below; one paragraph renders exactly as before. */
.hero__lede > p + p, .hero:has(> .hl:not([hidden])) .hero__lede > p + p { margin-top: 0.75em; }
.heading__copy > p + p { margin-top: 0.8em; }

/* =================================================================== HOME */

/* ------------------------------------------------------------ hero ----- */
/* The type is 1x and never transformed. Each take below brings its own planes, which read --hp
   (how far the hero has scrolled away) and, on a fine pointer, --mx/--my, each at its own rate. */
.hero {
  position: relative; min-height: 100vh; min-height: 100svh; overflow-x: clip;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; align-items: center;
  padding: calc(var(--bar-h) + 3vh) var(--sc-gutter) 5vh;
  --hp: 0; --mx: 0; --my: 0;
}
.hero__copy { position: relative; z-index: 4; grid-column: 1 / 8; grid-row: 1; max-width: 52rem; padding-bottom: 2vh; }
.hero__h {
  font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 740;
  font-size: clamp(2.2rem, 0.4rem + 4.4vw, 5.2rem);
  line-height: 1.02; letter-spacing: -0.034em; margin: 0; text-wrap: balance;
}
.hero__sub { margin-top: 26px; max-width: 30em; }
.hero__sub.fade-up, .band .lede.fade-up { --d: 520ms; }
.hero .actions.fade-up, .band .actions.fade-up, .band .status.fade-up { --d: 680ms; }


/* ---- C, G, H, I (shared): the headline carries it. Big type across the page, a fine rule above
   it with a crimson lead, and C's slow light behind */
.hero:has(> .hl:not([hidden])) { align-items: end; padding-bottom: clamp(44px, 11vh, 128px); }
.hero:has(> .hl:not([hidden])) .hero__copy { grid-column: 1 / -1; max-width: none; padding-bottom: 0; }
.hero:has(> .hl:not([hidden])) .hero__h {
  font-size: clamp(2.6rem, 0.3rem + 7.8vw, 10.5rem); line-height: 0.97; letter-spacing: -0.044em; max-width: 12.4em;
}
.hero:has(> .hl:not([hidden])) .hero__sub { margin-top: clamp(22px, 4vh, 40px); }
.hero:has(> .hl:not([hidden])) .hero__copy::before {
  content: ""; display: block; height: 1px; margin-bottom: clamp(26px, 5.5vh, 60px); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--night-accent) 0 56px, rgba(242,240,237,0.26) 56px, rgba(242,240,237,0.07) 72%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .js .hero:has(> .hl:not([hidden])) .hero__copy::before { animation: rule-in 1.5s var(--ease-io) 0.35s both; }
}
@media (max-width: 860px) {
  .hero:has(> .hl:not([hidden])) { align-items: stretch; justify-content: flex-end; padding-bottom: clamp(36px, 9vh, 80px); }
  .hero:has(> .hl:not([hidden])) .hero__h { font-size: clamp(2.3rem, 1.1rem + 5.2vw, 3.6rem); }
  .hero:has(> .hl:not([hidden])) .hero__copy::before { margin-bottom: 24px; }
}
@media (max-height: 720px) and (max-width: 860px) {
  .hero:has(> .hl:not([hidden])) .hero__h { font-size: 2.05rem; }
}
@media (max-height: 760px) and (min-width: 861px) {
  .hero:has(> .hl:not([hidden])) .hero__h { font-size: clamp(2.4rem, 0.4rem + 6vw, 7rem); }
}

@keyframes rule-in { from { scale: 0 1; } to { scale: 1 1; } }

/* ---- the hero (class hx): the headline runs the full width, and under it the business is drawn
   to plan. The drawing's markup and base styles are its finished state; with motion allowed and
   scripts on, it builds itself once on arrival in construction order (set-out, footings and slab,
   frame, walls, roof, openings, details, dimensions, then the notes), and the rule above the
   headline fills as it builds. After that nothing moves but the light. Steel for the building,
   crimson only where TradeSmart Systems' work is. */
.hx { display: contents; }
.hero:has(> .hx:not([hidden])) {
  grid-template-rows: auto auto; align-content: center; row-gap: clamp(24px, 4.2vh, 56px);
  padding-top: calc(var(--bar-h) + clamp(12px, 3vh, 40px)); padding-bottom: clamp(24px, 4vh, 52px);
  --band: clamp(150px, 30vh + 10px, 300px);
}
@media (min-height: 800px) { .hero:has(> .hx:not([hidden])) { --band: clamp(200px, 37vh, 400px); } }
@media (min-width: 861px) {
  /* exactly two lines at every desktop width: 10.2em takes "your trade business." (9.7em) but
     never "Smart Systems for your" (11.2em), and the size keeps 10.2em inside the page */
  .hero:has(> .hx:not([hidden])) .hero__h {
    font-size: min(clamp(2.6rem, 0.3rem + 7.8vw, 10.5rem), 14vh, calc((100vw - 2 * var(--sc-gutter)) / 10.7));
    max-width: 10.2em;
  }
  .hero:has(> .hx:not([hidden])) .actions .btn { min-height: 56px; padding: 0 28px; font-size: 1.125rem; }
  .hero:has(> .hx:not([hidden])) .actions .textlink { font-size: 1.125rem; }
  .hero:has(> .hx:not([hidden])) .hero__copy {
    display: grid; grid-template-columns: minmax(0, 40rem) auto; justify-content: start; align-items: end; column-gap: clamp(32px, 4vw, 72px);
  }
  .hero:has(> .hx:not([hidden])) .hero__copy::before,
  .hero:has(> .hx:not([hidden])) .hero__h { grid-column: 1 / -1; }
  .hero:has(> .hx:not([hidden])) .hero__lede { grid-column: 1; }
  .hero:has(> .hx:not([hidden])) .actions { grid-column: 2; margin-top: 0; flex-wrap: nowrap; }
}
/* the words arrive first: each line of the headline rises from under its own baseline and comes
   into focus, then the sub and the calls to action, on long expo-out curves */
@media (prefers-reduced-motion: no-preference) {
  .hero:has(> .hx:not([hidden])) .hero__h .ln__i {
    transition: transform 1400ms cubic-bezier(0.16, 1, 0.3, 1), opacity 1100ms cubic-bezier(0.16, 1, 0.3, 1), filter 1400ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 170ms + 100ms);
  }
  .js .hero:has(> .hx:not([hidden])) .hero__h.is-split:not(.is-lit) .ln__i { filter: blur(12px); }
  /* no flash of the fallback font: the headline waits, unseen, until it is split into its lines
     (the arrival's hard stop, reduced motion and no script all show it as it is) */
  .js .hero.is-arriving:has(> .hx:not([hidden])) .hero__h:not(.is-split) { opacity: 0; }
  .js .hero:has(> .hx:not([hidden])) .fade-up {
    transition: opacity 1300ms cubic-bezier(0.16, 1, 0.3, 1), transform 1300ms cubic-bezier(0.16, 1, 0.3, 1), filter 1300ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: var(--d, 0ms);
  }
  .js .hero.is-arriving:has(> .hx:not([hidden])) .fade-up { transform: translateY(20px); filter: blur(6px); }
  .hero:has(> .hx:not([hidden])) .hero__sub.fade-up { --d: 560ms; }
  .hero:has(> .hx:not([hidden])) .actions.fade-up { --d: 740ms; }
}

/* The rule above the headline is the build's progress. Crimson runs along the grey as the drawing
   builds, reaches the end with the last line, holds, then settles into one calm full-width hairline
   behind a short crimson lead. Its finished state is that settled line, so no script, reduced
   motion or a browser without registered properties all show it as it ends. */
@property --rule-load { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
@property --rule-lead { syntax: "<color>"; inherits: false; initial-value: #E0453C; }
.hero:has(> .hx:not([hidden])) .hero__copy::before {
  background: linear-gradient(90deg, var(--night-accent) 0 56px, var(--rule-lead) 56px max(56px, var(--rule-load)), rgba(242,240,237,0.09) max(56px, var(--rule-load)));
}
/* an option, off unless site.js turns it on (HERO_RULE_SCROLL): after the build, the rule becomes a
   quiet scroll-progress line for the hero alone */
.hero.rule-scroll:has(> .hx:not([hidden])) .hero__copy::before {
  background: linear-gradient(90deg, var(--night-accent) 0 max(56px, calc(var(--rule-scroll, 0) * 100%)), rgba(242,240,237,0.24) 0);
}
@media (prefers-reduced-motion: no-preference) {
  .js .hero.is-arriving:has(> .hx:not([hidden])) .hero__copy::before { --rule-load: 0%; --rule-lead: #E0453C; }
  .js .hero:not(.is-arriving):has(> .hx:not([hidden])) .hero__copy::before {
    animation: rule-in 0.9s var(--ease-io) 0.05s both, rule-load 4.95s cubic-bezier(0.37, 0, 0.63, 1) 0.15s both;
  }
}
@keyframes rule-load { from { --rule-load: 0%; --rule-lead: #E0453C; } to { --rule-load: 100%; --rule-lead: #E0453C; } }

/* ---- J, built to plan: an architect's front elevation of a large two-storey house, in four depth
   layers that drift a few pixels against each other with the pointer, with six notes round it. It builds itself once on
   arrival, in construction order; after that nothing moves but the drift. Monochrome linework. */
.elv {
  position: relative; z-index: 2; grid-column: 1 / -1; grid-row: 2; min-width: 0;
  display: flex; justify-content: center; height: var(--band);
}
.elv__fig { position: relative; height: 100%; aspect-ratio: 760 / 330; max-width: 100%; }
.hl { will-change: transform; }
@media (prefers-reduced-motion: no-preference) {
  .js .hero.is-arriving .elv { opacity: 0; }
}

/* ---- on a phone: the headline, then the elevation across the width */
@media (max-width: 860px) {
  .hero:has(> .hx:not([hidden])) {
    justify-content: center; gap: clamp(24px, 4vh, 40px);
    padding-top: calc(var(--bar-h) + 14px); padding-bottom: clamp(28px, 6vh, 56px);
  }
  .elv { height: auto; }
  .elv__fig { width: 100%; height: auto; max-height: 230px; }
}
@media (max-width: 860px) and (max-height: 700px) {
  .elv__fig { max-height: 136px; }
}

/* ---- the notes: what TradeSmart Systems does, as architectural notes round the drawing. A thin
   leader from a dot on each part runs out to the edge of the drawing, and the note sits beside it:
   a small caps title and one quiet line. Always there; with motion they draw in once at the end of
   the build (the leader, then its words), then everything stays still. */
.elv { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); justify-content: stretch; }

/* on a phone: the drawing with a small number on each part, and the six notes listed by number */
@media (max-width: 860px) {
  .elv { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 14px; row-gap: 12px; }
  .elv__fig { grid-column: 1 / -1; order: -1; margin-bottom: 6px; }
}
@media (max-width: 860px) and (max-height: 700px) {
  .elv { row-gap: 8px; }

}



/* ---------------------------------------------------------- routes ----- */
.route {
  position: relative; flex: 1 1 auto; display: flex; flex-direction: column;
  min-height: clamp(420px, 56vh, 560px); padding: clamp(28px, 3.2vw, 52px);
  border-radius: var(--r-lg); overflow: hidden; isolation: isolate;
  background: var(--day-surface); color: var(--day-ink);
  box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset, 0 1px 2px rgba(18,20,23,0.06),
    0 24px 60px -28px rgba(18,20,23,0.35);
}
.route h3 {
  margin: 22px 0 0; font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 740;
  font-size: clamp(2rem, 1.3rem + 2.4vw, 3.6rem); line-height: 1.02; letter-spacing: -0.03em; text-wrap: balance;
}
.route p { margin: 18px 0 0; max-width: 30em; font-size: clamp(1.02rem, 0.96rem + 0.3vw, 1.2rem); line-height: 1.55; color: var(--sc-ink-soft); text-wrap: pretty; }
.route .route__fact { color: var(--sc-ink); font-weight: 600; }
/* keyboard: anything animated on scroll snaps to its finished state the moment focus lands in it */
.wipe:focus-within, .next__panel:focus-within { animation: none !important; opacity: 1; translate: none; scale: none; clip-path: none; }
.led {
  width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto;
  background: #3AAE6A; box-shadow: 0 0 0 3px rgba(58,174,106,0.18), 0 0 10px rgba(58,174,106,0.6);
}
.led--build { background: var(--night-accent); box-shadow: 0 0 0 3px rgba(224,69,60,0.18), 0 0 10px rgba(224,69,60,0.7); }
@media (prefers-reduced-motion: no-preference) {
  .led--build { animation: led 2.4s ease-in-out infinite; }
}
@keyframes led { 50% { opacity: 0.35; box-shadow: 0 0 0 3px rgba(224,69,60,0.05), 0 0 2px rgba(224,69,60,0.2); } }

/* ------------------------------------------------------------- who ----- */
.who { padding: clamp(40px, 8vh, 110px) 0 clamp(80px, 12vh, 150px); }
.who .actions { margin-top: 26px; }

/* ------------------------------------------------------- who we are ---- */
.whoare__body { padding-top: 0.35em; max-width: 31em; }
/* One copy block: however many paragraphs he writes, they stack together in the right column. */
.whoare__copy > .whoare__body + .whoare__body { padding-top: 0; margin-top: 0.9em; }
.principles {
  list-style: none; margin: clamp(48px, 9vh, 104px) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px clamp(20px, 3vw, 48px);
}
.principle { position: relative; padding-top: 22px; border-top: 1px solid color-mix(in oklab, var(--day-ink) 14%, transparent); }
.principle::before { content: ""; position: absolute; left: 0; top: -1px; width: 40px; height: 2px; background: var(--day-accent); }
.principle__h {
  margin: 0; font-family: var(--sc-font-display); font-stretch: 110%; font-weight: 700;
  font-size: clamp(1.2rem, 1rem + 0.7vw, 1.6rem); line-height: 1.15; letter-spacing: -0.015em; color: var(--day-ink);
}
.principle__d { margin: 10px 0 0; max-width: 24em; font-size: clamp(1rem, 0.96rem + 0.2vw, 1.12rem); line-height: 1.55; color: var(--day-soft); text-wrap: pretty; }

/* ----------------------------------------------------------- close ----- */
.close { padding: clamp(90px, 16vh, 190px) 0 clamp(90px, 14vh, 160px); text-align: center; }
.close__h { max-width: 12em; margin-inline: auto; }
.close__line { margin: 22px auto 0; font-size: clamp(1.05rem, 0.95rem + 0.45vw, 1.35rem); color: var(--day-soft); }
.close .actions { justify-content: center; margin-top: 38px; }

/* ================================================= TITLE BANDS (pages) */
.band { position: relative; overflow: clip; padding: calc(var(--bar-h) + clamp(56px, 12vh, 150px)) 0 clamp(64px, 12vh, 140px); }
.band__copy .lede { margin-top: 26px; }
.band--short { padding-bottom: clamp(48px, 9vh, 100px); }

/* ============================================================ PACKAGE */
@keyframes sweep { from { background-position: 120% 0; } to { background-position: -30% 0; } }

.rail { gap: clamp(20px, 2.4vw, 40px); padding-inline: var(--sc-gutter); width: max-content; align-items: stretch; }
.get {
  flex: 0 0 auto; width: clamp(19rem, 32vw, 30rem); display: flex; flex-direction: column;
  padding: clamp(26px, 2.6vw, 40px); border-radius: var(--r-lg);
  background: var(--day-surface);
  box-shadow: inset 0 1px 0 #fff, 0 1px 2px rgba(18,20,23,0.06), 0 22px 50px -26px rgba(18,20,23,0.4);
}
@media (prefers-reduced-motion: no-preference) {
  .js .act-get[data-sc-act="pan"] .get {
    opacity: clamp(0.82, calc(0.82 + (var(--sc-p, 0) - var(--settle)) * 3), 1);
    translate: 0 calc(clamp(0, 1 - (var(--sc-p, 0) - var(--settle)) * 3, 1) * 26px);
  }
  .js .act-get .get:nth-of-type(1) { --settle: -1; }
  .js .act-get .get:nth-of-type(2) { --settle: 0.2; }
  .js .act-get .get:nth-of-type(3) { --settle: 0.45; }
}
.act-get[data-sc-act="flow"] .rail, html:not(.js) .rail {
  width: 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); row-gap: 28px;
  max-width: var(--sc-maxw); margin-inline: auto;
}
.act-get[data-sc-act="flow"] .rail > *, html:not(.js) .rail > * { width: auto; }

.how { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); grid-template-areas: "h h" "steps price"; column-gap: clamp(32px, 6vw, 110px); align-items: end; }
.steps { grid-area: steps; list-style: none; margin: 0; padding: 0; counter-reset: step; }
.step { counter-increment: step; position: relative; padding: 16px 0 16px 58px; border-top: 1px solid color-mix(in oklab, var(--day-ink) 12%, transparent); }
.step::before {
  content: counter(step); position: absolute; left: 0; top: 16px; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--sc-font-display); font-size: 0.9rem; font-weight: 700;
  color: #fff; background: var(--day-accent); font-variant-numeric: tabular-nums;
  box-shadow: 0 6px 14px -6px rgba(139,0,0,0.6);
}
.price {
  grid-area: price; padding: clamp(24px, 2.6vw, 40px); border-radius: var(--r-lg);
  background: var(--night); color: var(--night-ink);
  --sc-ink: var(--night-ink); --sc-ink-soft: var(--night-soft); --sc-accent: var(--night-accent);
  box-shadow: inset 0 1px 0 rgba(242,240,237,0.08), 0 30px 60px -30px rgba(18,20,23,0.7);
}
.price__num {
  margin: 0; font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 800;
  font-size: clamp(3rem, 1.6rem + 5vw, 6.4rem); line-height: 1.05; letter-spacing: -0.035em;
  color: var(--night-ink); font-variant-numeric: tabular-nums; padding-bottom: 0.06em;
}
.price__terms { margin: 14px 0 0; font-size: clamp(1.02rem, 0.95rem + 0.3vw, 1.2rem); line-height: 1.5; color: var(--night-ink); max-width: 24em; }
.price__terms + .price__terms { margin-top: 8px; color: var(--night-soft); }


/* ========================================================== TRADESMART */
.bp { position: absolute; inset: -40px; z-index: 0; pointer-events: none;
  background-image: linear-gradient(rgba(242,240,237,0.055) 1px, transparent 1px), linear-gradient(90deg, rgba(242,240,237,0.055) 1px, transparent 1px),
    linear-gradient(rgba(242,240,237,0.025) 1px, transparent 1px), linear-gradient(90deg, rgba(242,240,237,0.025) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  transform: translate3d(calc(var(--mx) * -16px), calc(var(--my) * -12px + var(--hp, 0) * 80px), 0);
  -webkit-mask-image: radial-gradient(70% 70% at 60% 45%, #000, transparent 80%);
  mask-image: radial-gradient(70% 70% at 60% 45%, #000, transparent 80%);
}
.ts-word {
  margin: 0; font-family: var(--sc-font-display); font-stretch: 125%; font-weight: 850;
  font-size: clamp(3rem, 0.6rem + 9.4vw, 10.5rem); line-height: 0.9; letter-spacing: -0.04em;
}
.ts-word .red { color: var(--night-accent); }
.ts-word .ch { display: inline-block; }
.status { display: inline-flex; align-items: center; gap: 12px; margin-top: 30px; padding: 10px 16px 10px 14px;
  border-radius: 999px; background: rgba(242,240,237,0.06); box-shadow: inset 0 0 0 1px rgba(242,240,237,0.12); font-weight: 600; }

.circuit { position: relative; list-style: none; margin: 0; padding: 0 0 0 64px; --p: var(--sc-p, 1); }
.circuit::before, .circuit::after { content: ""; position: absolute; left: 21px; top: 22px; bottom: 22px; width: 2px; border-radius: 2px; }
.circuit::before { background: var(--steel); }
.circuit::after { background: var(--day-accent); transform-origin: top; transform: scaleY(clamp(0, calc(var(--p) * 1.15), 1)); }
.node { position: relative; padding: 14px 0; --lit: clamp(0, calc((var(--p) - var(--t, 0)) * 12), 1); }
.node:nth-child(1) { --t: 0.02; } .node:nth-child(2) { --t: 0.2; } .node:nth-child(3) { --t: 0.38; }
.node:nth-child(4) { --t: 0.56; } .node:nth-child(5) { --t: 0.74; }
.node::before {
  content: ""; position: absolute; left: -54px; top: 50%; width: 24px; height: 24px; margin-top: -12px; border-radius: 50%;
  background: var(--day); box-shadow: inset 0 0 0 2px var(--steel);
}
.node::after {
  content: ""; position: absolute; left: -48px; top: 50%; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%;
  background: var(--day-accent); opacity: var(--lit); transform: scale(calc(0.4 + var(--lit) * 0.6));
  box-shadow: 0 0 12px rgba(139,0,0,0.5);
}

.next { padding: clamp(80px, 12vh, 150px) 0 clamp(30px, 6vh, 60px); }
.next__panel { border-radius: var(--r-lg); padding: clamp(28px, 4vw, 64px); background: var(--night); color: var(--night-ink);
  --sc-ink: var(--night-ink); --sc-ink-soft: var(--night-soft); --sc-accent: var(--night-accent);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(24px, 5vw, 80px); align-items: start;
  box-shadow: 0 40px 80px -40px rgba(18,20,23,0.7); }
.next__panel .lede { color: var(--night-soft); margin-top: 14px; }
.next__panel .label { margin-bottom: 14px; }
/* the word never breaks mid-word: on a phone it sizes to the width instead */
.ts-word { white-space: nowrap; font-size: min(clamp(3rem, 0.6rem + 9.4vw, 10.5rem), calc((100vw - 2 * var(--sc-gutter)) / 9.6)); }

/* the platform page: the idea, the life of a job (four stages on one rail), how it's built */
.idea { padding: clamp(40px, 8vh, 110px) 0 clamp(90px, 14vh, 170px); }
.idea__h { margin-top: 18px; max-width: 14em; }
.idea__line { margin-top: 26px; max-width: 34em; }
.life-sec { padding: clamp(80px, 12vh, 150px) 0 clamp(40px, 8vh, 90px); }
.life__intro .display { margin-top: 16px; }
.life__intro .lede { margin-top: 22px; }
.life { position: relative; list-style: none; margin: clamp(48px, 9vh, 100px) 0 0; padding: 0 0 0 clamp(40px, 5vw, 72px); counter-reset: stage; }
.life::before, .life::after { content: ""; position: absolute; left: 11px; top: 8px; bottom: 0; width: 2px; border-radius: 2px;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 180px), transparent); mask-image: linear-gradient(#000 calc(100% - 180px), transparent); }
.life::before { background: var(--steel); }
.life::after { background: var(--day-accent); transform-origin: top; }
.stage { counter-increment: stage; position: relative; display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 24px clamp(32px, 5vw, 90px); padding-bottom: clamp(56px, 10vh, 110px); }
.stage:last-child { padding-bottom: 0; }
.stage__head::before {
  content: ""; position: absolute; left: calc(-1 * clamp(40px, 5vw, 72px)); top: -5px; width: 24px; height: 24px; border-radius: 50%;
  background: var(--day); box-shadow: inset 0 0 0 2px var(--day-accent), 0 0 0 6px var(--day);
}
.stage__head::after {
  content: ""; position: absolute; left: calc(-1 * clamp(40px, 5vw, 72px) + 7px); top: 2px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--day-accent); box-shadow: 0 0 10px rgba(139,0,0,0.45);
}
.stage__head { align-self: start; position: sticky; top: calc(var(--bar-h) + 28px); }
.stage__h {
  margin: 0; font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 740;
  font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3.2rem); line-height: 1.02; letter-spacing: -0.03em; color: var(--day-ink);
}
.stage__h::before {
  content: counter(stage, decimal-leading-zero); display: block; margin-bottom: 12px;
  font-family: var(--sc-font-text); font-stretch: 100%; font-size: 0.82rem; font-weight: 600; letter-spacing: 0.14em; color: var(--day-accent);
}
.stage__d { margin: 14px 0 0; max-width: 20em; font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem); line-height: 1.5; color: var(--day-soft); text-wrap: pretty; }
.feats { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px clamp(20px, 3vw, 44px); }
.feat { position: relative; padding-top: 18px; border-top: 1px solid color-mix(in oklab, var(--day-ink) 14%, transparent); }
.feat::before { content: ""; position: absolute; left: 0; top: -1px; width: 32px; height: 2px; background: var(--day-accent); }
.feat__t {
  margin: 0; font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 700;
  font-size: clamp(1.1rem, 1rem + 0.4vw, 1.35rem); line-height: 1.2; letter-spacing: -0.012em; color: var(--day-ink); text-wrap: balance;
}
.feat__d { margin: 8px 0 0; max-width: 30em; line-height: 1.55; color: var(--day-soft); text-wrap: pretty; }
.appr { padding: clamp(80px, 12vh, 150px) 0 0; }
.appr__panel {
  border-radius: var(--r-lg); padding: clamp(28px, 5vw, 80px);
  background: var(--night); background-image: var(--card-tex); background-size: auto, 220px 220px; color: var(--night-ink);
  --sc-ink: var(--night-ink); --sc-ink-soft: var(--night-soft); --sc-accent: var(--night-accent);
  --card-tex: radial-gradient(90% 80% at 88% 12%, rgba(120,138,168,0.12), transparent 72%), var(--grain);
  box-shadow: 0 40px 80px -40px rgba(18,20,23,0.7);
}
.appr__head .display { margin-top: 16px; max-width: 13em; }
.appr__head .lede { margin-top: 24px; max-width: 38em; }
.appr__list { list-style: none; margin: clamp(40px, 7vh, 80px) 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 30px clamp(20px, 2.6vw, 40px); }
.appr__item { position: relative; padding-top: 20px; border-top: 1px solid rgba(242,240,237,0.16); }
.appr__item::before { content: ""; position: absolute; left: 0; top: -1px; width: 40px; height: 2px; background: var(--night-accent); }
.appr__t {
  margin: 0; font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 700;
  font-size: clamp(1.15rem, 1rem + 0.5vw, 1.45rem); line-height: 1.2; letter-spacing: -0.012em; color: var(--night-ink); text-wrap: balance;
}
.appr__d { margin: 10px 0 0; line-height: 1.55; color: var(--night-soft); text-wrap: pretty; }
.appr__goal {
  margin: clamp(40px, 7vh, 80px) 0 0; padding-top: clamp(28px, 4vh, 44px); border-top: 1px solid rgba(242,240,237,0.16); max-width: 30em;
  font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 650;
  font-size: clamp(1.3rem, 1rem + 1.2vw, 2.1rem); line-height: 1.25; letter-spacing: -0.018em; color: var(--night-ink); text-wrap: pretty;
}
.build { padding: clamp(80px, 12vh, 150px) 0 clamp(20px, 4vh, 40px); }
.heading { padding: clamp(80px, 12vh, 150px) 0 0; }
.heading__grid { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: 24px clamp(32px, 6vw, 110px); align-items: end; }
.heading__grid .display { margin-top: 16px; }
.build .display { margin-top: 16px; }

/* =============================================================== ABOUT */
.about-portrait { position: relative; justify-self: end; width: min(100%, 26rem); aspect-ratio: 4 / 5; border-radius: var(--r-lg); overflow: hidden;
  box-shadow: 0 40px 80px -40px rgba(0,0,0,0.8), inset 0 0 0 1px rgba(242,240,237,0.06);
  transform: translate3d(calc(var(--mx, 0) * 10px), calc(var(--hp, 0) * 70px), 0); }
.about-portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
.about-portrait::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255,240,225,0.22) 48%, transparent 62%) no-repeat;
  background-size: 260% 100%; background-position: 130% 0; mix-blend-mode: screen; }
@media (prefers-reduced-motion: no-preference) {
  .js .about-portrait::after { animation: sweep 2200ms var(--ease) 500ms both; }
}
.quote { margin: 0; }
.split { padding: clamp(80px, 12vh, 150px) 0; overflow: clip; }
.shift { border-radius: var(--r-lg); padding: clamp(28px, 3.6vw, 56px); min-height: 380px; display: flex; flex-direction: column; }
.shift h3 { margin: 18px 0 0; font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 740; font-size: clamp(2rem, 1.3rem + 2.4vw, 3.6rem); line-height: 1.02; letter-spacing: -0.03em; }
.shift p { margin: 16px 0 0; color: var(--sc-ink-soft); font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem); line-height: 1.55; max-width: 26em; }
.why { padding: clamp(40px, 6vh, 80px) 0 clamp(80px, 12vh, 140px); }

/* ============================================================= CONTACT */
.ways { padding: clamp(56px, 9vh, 110px) 0 clamp(40px, 8vh, 90px); }
.way { position: relative; display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr) auto; gap: 16px 40px; align-items: center;
  padding: clamp(24px, 3vw, 40px); border-radius: var(--r-lg); background: var(--day-surface);
  box-shadow: inset 0 1px 0 #fff, 0 18px 40px -26px rgba(18,20,23,0.4); }
.way + .way { margin-top: 18px; }
.way h2 { margin: 0; font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 720; font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.6rem); letter-spacing: -0.025em; line-height: 1.05; }
.way p { margin: 0; color: var(--day-soft); max-width: 34em; }
.way .btn, .way .textlink { justify-self: end; position: relative; z-index: 3; }
.chat-open { appearance: none; border: 0; background: none; cursor: pointer; padding: 0; font: inherit; }
.call { padding: clamp(40px, 8vh, 100px) 0 clamp(80px, 12vh, 140px); }
.beats { position: relative; list-style: none; margin: 0; padding: 0 0 0 40px; }
.beats::before { content: ""; position: absolute; left: 7px; top: 10px; bottom: 10px; width: 2px; background: var(--steel); }
.beats::after { content: ""; position: absolute; left: 7px; top: 10px; bottom: 10px; width: 2px; background: var(--day-accent); transform-origin: top; }
.ts-word { text-transform: uppercase; }
.close .label { justify-content: center; margin-bottom: 18px; }
.band--doc { padding-bottom: clamp(40px, 7vh, 80px); }
.band--doc .lede { margin-top: 18px; }
.doc__updated { margin: 14px 0 0; color: var(--night-soft); font-size: 0.95rem; }
.beat { position: relative; padding: 0 0 34px; }
.beat::before { content: ""; position: absolute; left: -40px; top: 6px; width: 16px; height: 16px; border-radius: 50%; background: var(--day); box-shadow: inset 0 0 0 2px var(--day-accent); }
.beat h3 { margin: 0; font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 700; font-size: clamp(1.15rem, 1rem + 0.6vw, 1.5rem); letter-spacing: -0.012em; }
.beat p { margin: 6px 0 0; color: var(--day-soft); max-width: 34em; }

/* =============================================================== LEGAL */
.readbar { position: fixed; left: 0; right: 0; top: var(--bar-h); height: 2px; z-index: 61; background: var(--day-accent); transform-origin: left; transform: scaleX(0); display: none; }
.doc { padding: clamp(56px, 9vh, 110px) 0 clamp(80px, 12vh, 140px); }
.doc__grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 8fr); gap: clamp(28px, 5vw, 90px); align-items: start; }
.toc { position: sticky; top: calc(var(--bar-h) + 28px); }
.toc ol { list-style: none; margin: 14px 0 0; padding: 0; }
.toc li + li { margin-top: 8px; }
.toc a { color: var(--day-soft); text-decoration: none; font-size: 0.95rem; }
@media (hover: hover) and (pointer: fine) { .toc a:hover { color: var(--day-ink); text-decoration: underline; text-underline-offset: 0.25em; } }
.prose { max-width: 42rem; }
.prose h2 { margin: 56px 0 0; font-family: var(--sc-font-display); font-stretch: 108%; font-weight: 720; font-size: clamp(1.4rem, 1.1rem + 1vw, 2rem); letter-spacing: -0.02em; line-height: 1.15; scroll-margin-top: calc(var(--bar-h) + 24px); }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose li { color: var(--day-ink); line-height: 1.7; }
.prose p { margin: 14px 0 0; }
.prose ul { margin: 14px 0 0; padding-left: 1.2em; }
.prose li + li { margin-top: 8px; }
.prose a { color: var(--day-accent); }
.prose strong { font-weight: 650; }

/* ================================================================ CHAT */
.chat { position: fixed; right: 16px; bottom: 16px; z-index: 70; }
.chat[hidden] { display: none; }
.chat__launch {
  width: 58px; height: 58px; padding: 0; border-radius: 50%; border: 0; cursor: pointer;
  display: grid; place-items: center; color: #FFFFFF;
  /* the chrome TS mark reads best on the night ground, as in the header; crimson ring for the brand */
  background: radial-gradient(circle at 50% 35%, #232830, var(--night-surface) 70%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 0 2px var(--brand), 0 0 0 3px rgba(224,69,60,0.28), 0 12px 26px -8px rgba(0,0,0,0.6);
  transition: scale 140ms var(--ease), box-shadow 140ms var(--ease);
}
.chat__mark { width: 46px; height: 46px; display: block; pointer-events: none; }
.chat__avatar { flex: none; width: 34px; height: 34px; display: block; margin: -6px -8px -6px -6px; }
.chat__head .chat__title { flex: 1 1 auto; }
.chat__launch:active { scale: 0.96; }
@media (hover: hover) and (pointer: fine) { .chat__launch:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 0 2px var(--night-accent), 0 0 0 4px rgba(224,69,60,0.35), 0 12px 26px -8px rgba(0,0,0,0.6); } }
.chat__launch:focus-visible, .chat__panel :focus-visible { outline: 2px solid var(--night-accent); outline-offset: 3px; }
.chat__panel {
  position: absolute; right: 0; bottom: 66px;
  width: min(380px, calc(100vw - 32px)); max-height: min(540px, calc(100svh - var(--bar-h) - 100px));
  display: flex; flex-direction: column; color: var(--night-ink);
  background: linear-gradient(180deg, rgba(27,31,38,0.985), rgba(16,19,24,0.99));
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  border-radius: 18px; overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.07), 0 0 0 1px rgba(242,240,237,0.1), 0 28px 70px -20px rgba(0,0,0,0.7);
}
.chat__panel::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--night-accent) 0 64px, rgba(224,69,60,0.25) 64px, transparent 80%); }
@media (prefers-reduced-motion: no-preference) {
  .chat__panel:not([hidden]) { animation: chat-in 280ms var(--ease) both; }
}
@keyframes chat-in { from { opacity: 0; translate: 0 10px; } to { opacity: 1; translate: 0 0; } }
.chat__panel[hidden] { display: none; }
.chat__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 12px 12px 18px; border-bottom: 1px solid rgba(242,240,237,0.08); }
.chat__title { margin: 0; font-family: var(--sc-font-display); font-stretch: 110%; font-weight: 650; font-size: 1rem; }
.chat__close { flex: none; width: 40px; height: 40px; border: 0; border-radius: 10px; background: none; color: var(--night-soft); cursor: pointer; display: grid; place-items: center; }
@media (hover: hover) and (pointer: fine) { .chat__close:hover { background: rgba(242,240,237,0.07); color: var(--night-ink); } }
.chat__log { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 8px; display: flex; flex-direction: column; gap: 10px; min-height: 160px; }
.chat__msg { max-width: 86%; padding: 10px 13px; border-radius: 14px; font-size: 0.95rem; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat__msg--bot { align-self: flex-start; background: rgba(242,240,237,0.07); color: var(--night-ink); border-bottom-left-radius: 5px; box-shadow: inset 0 0 0 1px rgba(242,240,237,0.06); }
.chat__msg--you { align-self: flex-end; background: var(--brand); color: #FFFFFF; border-bottom-right-radius: 5px; }
.chat__msg a { color: #FFB4AE; }
.chat__msg--busy { color: var(--night-soft); }
.chat__dots { display: inline-flex; gap: 4px; align-items: center; height: 1em; }
.chat__dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--night-soft); opacity: 0.55; }
@media (prefers-reduced-motion: no-preference) {
  .chat__dots i { animation: chat-dot 1.2s ease-in-out infinite; }
  .chat__dots i:nth-child(2) { animation-delay: 0.15s; }
  .chat__dots i:nth-child(3) { animation-delay: 0.3s; }
}
@keyframes chat-dot { 0%, 80%, 100% { opacity: 0.35; } 40% { opacity: 1; } }
.chat__book {
  align-self: flex-start; display: inline-flex; align-items: center; min-height: 40px; padding: 0 16px;
  border-radius: 999px; background: var(--brand); color: #FFFFFF; font-weight: 600; font-size: 0.92rem;
  text-decoration: none; box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 0 0 1px rgba(224,69,60,0.35);
}
@media (hover: hover) and (pointer: fine) { .chat__book:hover { background: #A30E0E; } }
.chat__note { margin: 0; padding: 8px 16px 0; font-size: 0.78rem; line-height: 1.45; color: var(--night-soft); }
.chat__note a { color: var(--night-soft); text-decoration: underline; text-underline-offset: 0.2em; }
.chat__form { display: flex; gap: 8px; padding: 10px 12px 12px; }
.chat__input { flex: 1 1 auto; min-width: 0; min-height: 46px; padding: 0 14px; border-radius: 12px; border: 1px solid rgba(242,240,237,0.16); background: rgba(8,10,13,0.55); color: var(--night-ink); font: inherit; font-size: 16px; }
.chat__input:focus { border-color: rgba(224,69,60,0.6); }
.chat__input::placeholder { color: #8E8A87; }
.chat__send { min-height: 46px; padding: 0 16px; border: 0; border-radius: 12px; cursor: pointer; background: var(--brand); color: #FFFFFF; font: inherit; font-weight: 600; }
.chat__send:disabled { opacity: 0.6; cursor: default; }
@media (hover: hover) and (pointer: fine) { .chat__send:not(:disabled):hover { background: #A30E0E; } }
@media (max-width: 560px) {
  .chat { right: 12px; bottom: 12px; }
  .chat__panel { position: fixed; left: 12px; right: 12px; bottom: 76px; width: auto;
    max-height: calc(100svh - var(--bar-h) - 96px); }
}

/* ================================================ REGISTER INTEREST
   The form on /tradesmart/ (#register). No script: a plain POST, and the server sends the browser
   back to #thanks or to the message for what went wrong, which :target shows. With script, site.js
   posts in place and shows the same words. Every word lives in the page. */
.band__go { margin-top: 26px; }
.next__go { margin: 22px 0 0; }
.interest { padding: clamp(40px, 7vh, 90px) 0 clamp(30px, 6vh, 60px); scroll-margin-top: calc(var(--bar-h) + 12px); }
.interest__panel {
  position: relative; border-radius: var(--r-lg); padding: clamp(28px, 4vw, 64px);
  background: var(--day-surface); color: var(--day-ink);
  --sc-ink: var(--day-ink); --sc-ink-soft: var(--day-soft); --sc-accent: var(--day-accent);
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(28px, 5vw, 80px); align-items: start;
  box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset, 0 1px 2px rgba(18,20,23,0.06), 0 24px 60px -28px rgba(18,20,23,0.35);
}
.interest__head .display { margin-top: 14px; max-width: 11em; }
.interest__head .lede { margin-top: 18px; max-width: 24em; }
.interest__form { display: grid; gap: 20px; }
.interest__form[hidden] { display: none; }
.interest__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.field { display: grid; gap: 8px; min-width: 0; margin: 0; }
.field--set { border: 0; padding: 0; }
.field__l { padding: 0; font-weight: 600; font-size: 1rem; line-height: 1.35; color: var(--day-ink); }
.field__l--sub { font-weight: 500; color: var(--day-soft); }
.field__req { font-weight: 400; color: var(--day-soft); }
.field__hint { margin: -2px 0 2px; font-size: 0.95rem; color: var(--day-soft); }
.field__i {
  width: 100%; min-height: 50px; padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--steel); background: var(--day); color: var(--day-ink);
  font: inherit; font-size: 16px; line-height: 1.4;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease);
}
.field__i--area { min-height: 112px; resize: vertical; line-height: 1.5; }
.field__i:focus { border-color: var(--day-accent); background: var(--day-surface); }
.field__i:focus-visible { outline: 2px solid var(--day-accent); outline-offset: 2px; }
.field__i[aria-invalid="true"] { border-color: var(--day-accent); }
.field__err { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--day-accent); }
.interest__send { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px; margin-top: 4px; }
.interest__send .btn { border: 0; cursor: pointer; }
.interest__send .btn:disabled { cursor: progress; opacity: 0.75; }
.interest__status { margin: 0; font-weight: 600; color: var(--day-ink); }
.interest__status a, .interest__flash a, .interest__small a { color: inherit; text-underline-offset: 0.2em; }
.interest__small { margin: 0; max-width: 42em; font-size: 0.92rem; line-height: 1.55; color: var(--day-soft); }
.interest__done:target, .interest__flash:target { display: block; }
.interest__done:target ~ .interest__form { display: none; }
.interest__done { padding: 24px 26px; border-radius: 14px; background: var(--day);
  box-shadow: inset 0 0 0 1px rgba(18,20,23,0.08); }
.interest__done-h { margin: 0; font-family: var(--sc-font-display); font-stretch: 110%; font-weight: 720;
  font-size: clamp(1.35rem, 1rem + 1vw, 1.9rem); line-height: 1.15; letter-spacing: -0.015em; }
.interest__done-d { margin: 10px 0 0; line-height: 1.55; color: var(--day-soft); }
.interest__flash { margin: 0 0 20px; padding: 14px 18px; border-radius: 12px; font-weight: 600; line-height: 1.5;
  color: var(--day-ink); background: var(--day); box-shadow: inset 3px 0 0 var(--day-accent); }
.interest__done:focus, .interest__flash:focus { outline: none; }
.interest__done:focus-visible, .interest__flash:focus-visible { outline: 2px solid var(--day-accent); outline-offset: 3px; }
/* an off-screen field, out of the tab order */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 860px) { .interest__panel { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 560px) { .interest__row { grid-template-columns: minmax(0, 1fr); } }

/* ================================================ SCROLL-LINKED MOTION
   Native scroll-driven animations. Only where supported AND motion is welcome, so every
   other browser, reduced motion and JS-off all get the finished static page. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* long ease-out curves: most of the move happens early, and every reveal has landed by the time
       its element is fully on screen */

    .wipe { animation: wipe-up both cubic-bezier(0.5, 0, 0.2, 1); animation-timeline: view(); animation-range: entry 0% entry 95%; }
    @keyframes wipe-up { from { clip-path: inset(100% 0 0 0 round var(--r-lg)); } to { clip-path: inset(0 0 0 0 round var(--r-lg)); } }

    .split { view-timeline-name: --split; }

    .beats { view-timeline-name: --beats; }
    .beats::after { animation: draw-down linear both; animation-timeline: --beats; animation-range: entry 40% cover 55%; }
    @keyframes draw-down { from { transform: scaleY(0); } to { transform: scaleY(1); } }

    .readbar { display: block; animation: grow linear both; animation-timeline: scroll(root); }
    @keyframes grow { to { transform: scaleX(1); } }

    .next__panel { animation: wipe-left both cubic-bezier(0.5, 0, 0.2, 1); animation-timeline: view(); animation-range: entry 0% entry 60%; }
    @keyframes wipe-left { from { clip-path: inset(0 100% 0 0 round var(--r-lg)); } to { clip-path: inset(0 0 0 0 round var(--r-lg)); } }

    .life { view-timeline-name: --life; }
    .life::after { animation: draw-down linear both; animation-timeline: --life; animation-range: entry 30% exit 60%; }
  }
}

/* ===================================================== ENTRY REVEALS
   Blocks that come up once as they are scrolled to (data-sc-in): out of a soft blur, on long
   expo-out curves. A staggered group reveals through its children only, so nothing fades twice;
   neighbours in a row of a grid follow each other in reading order. Headings rise line by line
   (site.js marks them h-rise), and the page titles and their lines arrive the same way. Reduced
   motion, no script and the failsafe all get the finished page. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-sc-in], .js [data-sc-stagger] > * {
    transform: translate3d(0, 24px, 0); filter: blur(6px);
    transition: opacity 900ms cubic-bezier(0.16, 1, 0.3, 1), transform 1100ms cubic-bezier(0.16, 1, 0.3, 1), filter 900ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .js [data-sc-in].sc-in, .js [data-sc-stagger] > .sc-in { transform: none; filter: none; }
  .js [data-sc-in][data-sc-stagger] { opacity: 1; transform: none; filter: none; }

  .js .h-rise .ln__i {
    transition: transform 1150ms cubic-bezier(0.16, 1, 0.3, 1), opacity 800ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 110ms);
  }
  .js .h-rise.is-split:not(.is-lit) .ln__i { transform: translateY(108%); opacity: 0; }
  .js [data-sc-stagger] > .h-rise.is-split, .js .h-rise.is-split[data-sc-in] { opacity: 1; transform: none; filter: none; }

  .js [data-lines] .ln__i {
    transition: transform 1300ms cubic-bezier(0.16, 1, 0.3, 1), opacity 1000ms cubic-bezier(0.16, 1, 0.3, 1), filter 1300ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 150ms + 80ms + var(--d, 0ms));
  }
  .js [data-lines].is-split:not(.is-lit) .ln__i { filter: blur(10px); }
  .js .fade-up {
    transition: opacity 1200ms cubic-bezier(0.16, 1, 0.3, 1), transform 1200ms cubic-bezier(0.16, 1, 0.3, 1), filter 1200ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: var(--d, 0ms);
  }
  .js .is-arriving .fade-up { transform: translateY(18px); filter: blur(6px); }
  .ch { transition: transform 1000ms cubic-bezier(0.16, 1, 0.3, 1), opacity 900ms cubic-bezier(0.16, 1, 0.3, 1), filter 1000ms cubic-bezier(0.16, 1, 0.3, 1); transition-delay: calc(var(--i, 0) * 45ms + 120ms); }
  .js [data-chars].is-split:not(.is-lit) .ch { filter: blur(8px); }
}
@media (prefers-reduced-motion: no-preference) and (min-width: 701px) {
  .js .feats > :nth-child(2n) { transition-delay: 110ms; }
}
@media (prefers-reduced-motion: no-preference) and (min-width: 701px) and (max-width: 980px) {
  .js .principles--build > :nth-child(2n), .js .appr__list > :nth-child(2n) { transition-delay: 110ms; }
}
@media (prefers-reduced-motion: no-preference) and (min-width: 981px) {
  .js .principles--build > :nth-child(3n+2), .js .appr__list > :nth-child(4n+2) { transition-delay: 110ms; }
  .js .principles--build > :nth-child(3n+3), .js .appr__list > :nth-child(4n+3) { transition-delay: 220ms; }
  .js .appr__list > :nth-child(4n+4) { transition-delay: 330ms; }
}

/* ------------------------------------------------------------- faq ----- */
/* Native <details>: opens and closes with no script, by keyboard, and with reduced motion.
   Each answer is one copy block of plain <p>s, so it stays editable as a block. */
.faq { padding: clamp(64px, 11vh, 140px) 0 clamp(24px, 5vh, 64px); }
.faq__list { position: relative; border-bottom: 1px solid color-mix(in oklab, var(--day-ink) 14%, transparent); }
.faq__list::before { content: ""; position: absolute; left: 0; top: -1px; width: 40px; height: 2px; background: var(--day-accent); z-index: 1; }
.faq__item { border-top: 1px solid color-mix(in oklab, var(--day-ink) 14%, transparent); }
.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  min-height: 48px; padding: clamp(18px, 2.4vh, 26px) 0; cursor: pointer; list-style: none;
  color: var(--day-ink); border-radius: 4px;
}
.faq__q::-webkit-details-marker { display: none; }
/* the circled plus is DRAWN (two 2px bars centred in the circle by background-position), never a "+" glyph, and it
   turns 45deg into an X when the answer opens, the same icon as the film and Apple-style FAQs */
.faq__q::after {
  content: ""; flex: none; box-sizing: border-box; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--day-ink) 18%, transparent);
  background:
    linear-gradient(currentColor, currentColor) 50% 50% / 12px 2px no-repeat,
    linear-gradient(currentColor, currentColor) 50% 50% / 2px 12px no-repeat;
  transition: border-color 200ms var(--ease), color 200ms var(--ease), rotate 260ms var(--ease);
}
.faq__item[open] > .faq__q::after {
  color: var(--day-accent); border-color: color-mix(in oklab, var(--day-accent) 45%, transparent);
  rotate: 45deg;
}
@media (hover: hover) and (pointer: fine) {
  .faq__q:hover::after { border-color: color-mix(in oklab, var(--day-ink) 40%, transparent); }
}
.faq__q:focus-visible { outline: 2px solid var(--day-accent); outline-offset: 4px; }
@media (prefers-reduced-motion: no-preference) {
  /* where the browser can animate a details panel, it eases open; elsewhere it simply opens */
  .faq { interpolate-size: allow-keywords; }
  .faq__item::details-content {
    block-size: 0; overflow: clip; opacity: 0;
    transition: block-size 380ms var(--ease), opacity 300ms var(--ease), content-visibility 380ms allow-discrete;
  }
  .faq__item[open]::details-content { block-size: auto; opacity: 1; }
}
@media (max-width: 860px) {
  .faq__q { gap: 16px; }
  .faq__q::after { width: 30px; height: 30px; }
}
@media print {
  .faq__item::details-content { block-size: auto; opacity: 1; content-visibility: visible; }
}

/* ============================================================= MOBILE */
@media (max-width: 980px) {
  .nav { display: none; }
  .menu { display: block; }
  .bar__sep, .bar__end > .btn-login { display: none; }
  .btn-login--menu { display: inline-flex; align-self: stretch; min-height: 52px; margin-top: 22px; position: relative; }
  .btn-login--menu::before { content: ""; position: absolute; left: 0; right: 0; top: -12px; height: 1px; background: rgba(242,240,237,0.18); }
  .stage { grid-template-columns: 1fr; }
  .stage__head { position: relative; top: auto; }
  .principles--build, .appr__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .heading__grid { grid-template-columns: 1fr; }
  .next__panel, .doc__grid { grid-template-columns: 1fr; }
  .toc { position: static; }
  .way { grid-template-columns: 1fr; }
  .way .btn, .way .textlink { justify-self: start; }
  .how { grid-template-columns: 1fr; grid-template-areas: "h" "steps" "price"; }
  .price { margin-top: 18px; }
}
@media (max-width: 860px) {
  .hero { display: flex; flex-direction: column; justify-content: center; align-items: stretch; gap: 44px; padding: calc(var(--bar-h) + 14px) var(--sc-gutter) 26px; min-height: 100svh; }
  .hero__copy { padding: 0; max-width: none; }
  .hero__h { font-size: clamp(1.8rem, 1rem + 3.6vw, 2.6rem); }
  .hero__sub { margin-top: 14px; font-size: 1rem; }
  .hero .actions { margin-top: 20px; }
}
@media (max-width: 700px) {
  .principles, .principles--build, .appr__list { grid-template-columns: 1fr; }
  .appr__panel { padding: 28px 22px; }
  .feats { grid-template-columns: 1fr; gap: 24px; }
  .life { padding-left: 36px; }
  .life::before, .life::after { left: 9px; }
  .stage__head::before { left: -36px; width: 20px; height: 20px; top: -3px; }
  .stage__head::after { left: -30px; width: 8px; height: 8px; top: 3px; }
  .btn--bar { min-height: 38px; padding: 0 13px; font-size: 0.86rem; }
  .menu > summary { min-height: 38px; min-width: 40px; padding: 0 11px; justify-content: center; }
  .menu__txt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bar { gap: 10px; }
  .bar__end { gap: 8px; }
  .lockup-day { gap: 10px; }
  .lockup-day__mark { height: 24px; }
  .lockup-chrome { gap: 10px; --ms: 0.1; --ws: 0.24; }
  .wordmark__top { font-size: 1.12rem; }
  .wordmark__sub { font-size: 0.52rem; }
  .actions { margin-top: 22px; gap: 12px 20px; }
  .step { padding: 12px 0 12px 46px; }
  .step::before { width: 28px; height: 28px; top: 12px; font-size: 0.8rem; }
  .price__num { font-size: 2.8rem; }
  .price__terms { font-size: 0.98rem; margin-top: 8px; }
  .get { width: 82vw; }
  .shift { min-height: 0; }
  .foot__in { grid-template-columns: 1fr; padding-bottom: 88px; }
  .foot__legal { flex-direction: column; gap: 2px; }
  .foot__legal .dot { display: none; }
  .route { min-height: 360px; }
  .circuit { padding-left: 52px; }
  .node::before { left: -46px; } .node::after { left: -40px; }
  .circuit::before, .circuit::after { left: 17px; }
}
@media (max-height: 720px) and (max-width: 860px) {
  .hero__h { font-size: 1.7rem; }
  .hero__sub { font-size: 0.95rem; }
}
@media (max-height: 760px) and (min-width: 861px) {
  .hero__h { font-size: clamp(2rem, 0.9rem + 3vw, 3.9rem); }
  .steps .step { padding-block: 10px; }
}

/* ===================================================== REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  .bar, .btn, .ln__i, .fade-up { transition-duration: 0ms !important; transition-delay: 0ms !important; }
  .bp, .about-portrait { transform: none !important; }
  .js [data-lines].is-split:not(.is-lit) .ln__i { transform: none; opacity: 1; }
  /* scroll-lit content is simply lit: the reading order does the work, not the scroll */
  .circuit { --p: 1; }
  /* entry reveals are simply there */
  [data-sc-in], [data-sc-stagger] > * { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
}

/* ============================================================ FAILSAFE */
html:not(.js) [data-sc-cue], html:not(.js) [data-sc-in], html:not(.js) [data-sc-stagger] > *,
html:not(.js) .sc-split__i, html:not(.js) [data-sc-parallax], html:not(.js) .get,
.sc-failsafe [data-sc-cue], .sc-failsafe [data-sc-in], .sc-failsafe [data-sc-stagger] > *,
.sc-failsafe .sc-split__i, .sc-failsafe [data-sc-parallax], .sc-failsafe .get,
.sc-failsafe .ln__i, .sc-failsafe .fade-up, .sc-failsafe .ch {
  opacity: 1 !important; transform: none !important; translate: none !important; filter: none !important;
}
html:not(.js) [data-sc-reveal],
.sc-failsafe [data-sc-reveal] { clip-path: none !important; }
.sc-failsafe [data-sc-pan] { transform: none !important; }
.sc-failsafe .sc-act--pinned { height: auto !important; }
.sc-failsafe .sc-stage { position: relative !important; height: auto !important; min-height: 0; overflow: visible !important; }
html:not(.js) .circuit, .sc-failsafe .circuit { --p: 1; }

/* ================================================== SIGNATURE MOMENTS
   Six scroll-tied moments. Each one is driven by where the page is, so it runs backwards on the
   way up and holds still when the page does. The markup and the defaults ARE the finished state:
   no script, reduced motion, the failsafe or an unsupported browser all show it drawn, lit and
   settled. The line drawings share one language: thin ink strokes, crimson only on one detail. */

/* the drawing strokes (the kit on /starter-package/, the dashboard on /tradesmart/) */
.kit .ln, .dash .ln { fill: none; stroke: color-mix(in oklab, var(--day-ink) 72%, transparent); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.kit .ln--soft, .dash .ln--soft { stroke: color-mix(in oklab, var(--day-ink) 40%, transparent); }
.kit .ln--acc, .dash .ln--acc { stroke: var(--day-accent); stroke-width: 1.6; }
.kit .fl, .dash .fl { fill: #FFFFFF; }
.dash .ln--dot { stroke-width: 4; }
/* each group draws over its own stretch of the progress (--kp / --sp, written by site.js), then fills */
.js .dash__g { --d: clamp(0, (var(--sp, 5) - var(--a)) / var(--w), 1); --f: clamp(0, (var(--sp, 5) - var(--a) - var(--w) * 0.75) / (var(--w) * 0.45), 1); }
.js .kit .ln, .js .dash .ln { stroke-dasharray: 1 1; stroke-dashoffset: calc(1 - var(--d)); stroke-opacity: clamp(0, var(--d) * 12, 1); }
.js .kit .fl, .js .dash .fl { fill-opacity: var(--f); }
.dash__frame { --a: 0; --w: 0.45; }
.dash__p1 { --a: 0.25; --w: 0.7; }
.dash__p2 { --a: 1; --w: 0.75; }
.dash__p3 { --a: 2; --w: 0.75; }
.dash__p4 { --a: 3; --w: 0.75; }
.dash__p5 { --a: 4; --w: 0.75; }

/* 1. Who we are: the statement lights up word by word, grey to full ink. The grey is still over
   4.5:1 on the light ground, so it reads at every point. site.js splits the words and writes --lp. */
.whoare__copy { --lw-dim: #626873; }
.whoare__body .lw { color: color-mix(in oklab, var(--day-ink) calc(clamp(0, (var(--lp, 1) * (var(--n) + 9) - var(--i)) / 9, 1) * 100%), var(--lw-dim)); }

/* 3. What you get: the kit sits under the lede; drawn by the scroll through the act */
.kit { display: block; width: 100%; max-width: 27rem; height: auto; margin-top: clamp(22px, 4vh, 44px); overflow: visible; }
.act-get[data-sc-act="flow"] .kit, html:not(.js) .kit { max-width: 30rem; }

/* 4. The whole life of a job: the platform sketch. Desktop with room: it sits at the top of the
   stage column and stays there while the stages pass, each stage's heading holding just under it.
   Anywhere else: it sits above the list and draws as it comes on screen. */
.life-frame { position: relative; margin-top: clamp(48px, 9vh, 100px); }
.life-frame > .life { margin-top: 0; }
.life__rail { margin: 0 0 clamp(36px, 6vh, 64px); }
.dash { display: block; width: 100%; max-width: 22rem; height: auto; overflow: visible; }
@media (min-width: 981px) and (min-height: 760px) and (prefers-reduced-motion: no-preference) {
  .js .life-frame { --sk: 13.5rem; }
  .js .life__rail { position: absolute; z-index: 2; top: 0; bottom: 0; margin: 0; pointer-events: none;
    left: clamp(40px, 5vw, 72px); width: calc((100% - clamp(40px, 5vw, 72px) - clamp(32px, 5vw, 90px)) / 3); }
  .js .dash { position: sticky; top: calc(var(--bar-h) + 28px); max-width: 18rem; }
  .js .life .stage__head { padding-top: calc(var(--sk) + 34px); }
  .js .life .stage__head::before { top: calc(var(--sk) + 29px); }
  .js .life .stage__head::after { top: calc(var(--sk) + 36px); }
}
.sc-failsafe .life__rail { position: static !important; margin: 0 0 40px !important; width: auto !important; }
.sc-failsafe .dash { position: static !important; }
.sc-failsafe .life .stage__head { padding-top: 0 !important; opacity: 1 !important; }
.sc-failsafe .life .stage__head::before { top: -5px !important; }
.sc-failsafe .life .stage__head::after { top: 2px !important; }

/* 5. About: the portrait is drafted. A frame draws its outline, construction lines run past its
   corners, then the photo wipes in inside it. */
.who { overflow-x: clip; }
.dl { background: color-mix(in oklab, var(--day-ink) 55%, transparent); }

/* 6. Big section headings: a thin crimson rule draws across under them as they come on screen */
main h2.display--lg::after, main h2.display--xl::after {
  content: ""; display: block; margin-top: 0.2em; width: min(4.2rem, 32%); height: 2px; border-radius: 2px;
  background: var(--sc-accent, var(--day-accent)); transform-origin: 0 50%; pointer-events: none;
}
.close h2.close__h::after { margin-inline: auto; transform-origin: 50% 50%; }
/* 6b. Key prices count up once when they arrive: site.js wraps them at run time; the page holds
   the final figure, so no script and reduced motion simply read it */
.num { display: inline-block; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {


    /* 6. the heading rule, drawn under the line reveal (pinned scenes keep theirs still) */
    main h2.display--lg, main h2.display--xl { view-timeline-name: --hl; }
    main section:not(.sc-act--pinned) h2.display--lg::after, main section:not(.sc-act--pinned) h2.display--xl::after {
      animation: h-rule linear both; animation-timeline: --hl; animation-range: entry 15% entry 100%;
    }
    @keyframes h-rule { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  }
}

/* ====================================================== SECTION WORLDS
   Each section is its own world. The ribbed glass now belongs to each page's top band only. Every
   section under it sits in its own world: its own opaque ground, and its own way of arriving.
   Each ground is drawn on the section's ::before, shaped by --wp (0 as the section's top comes up
   the screen, 1 once it is a quarter of the way down; site.js initWorlds writes it). With no
   script, reduced motion or a failsafe, --wp stays 1: every ground is simply there, finished.
   The words are never hidden by a world; only grounds and decoration move. */
section[data-world] { position: relative; isolation: isolate; background-color: transparent; --wp: 1; }
section[data-world]::before { content: ""; position: absolute; inset: 0; z-index: -2; pointer-events: none; }
.world__fx { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }

/* ---- paper: warm off-white, wiped across from the left on a slant */
section[data-world="paper"] {
  --sc-canvas: #EEEAE3; --sc-surface: #FFFFFF;
  --sc-ink: #15130F; --sc-ink-soft: #57524A; --sc-accent: var(--brand); --sc-accent-ink: #FFFFFF;
  --sc-shadow-color: 30 20% 30%;
  color: var(--sc-ink);
}
section[data-world="paper"]::before {
  background:
    radial-gradient(120% 90% at 10% 0%, rgba(255,255,255,0.7), transparent 60%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='p'><feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.3  0 0 0 0 0.25  0 0 0 0 0.2  0 0 0 0.09 0'/></filter><rect width='240' height='240' filter='url(%23p)'/></svg>"),
    #EEEAE3;
  /* the paper's words are dark, so the wipe finishes by halfway (--wp 0.5): the page is covered
     before the first line of copy is far enough up the screen to be read */
  clip-path: polygon(0 0, calc(var(--wp) * 260%) 0, calc(var(--wp) * 260% - 30%) 100%, 0 100%);
}
section[data-world="paper"] .display { color: var(--sc-ink); }

/* ---- crimson: the brand red, a rounded panel that grows out to the full width */
section[data-world="crimson"] {
  --sc-canvas: #7A0000; --sc-surface: #5E0000;
  --sc-ink: #FFF6F2; --sc-ink-soft: #F2C9C2; --sc-accent: #FFFFFF; --sc-accent-ink: #7A0000;
  --sc-shadow-color: 0 60% 8%;
  color: var(--sc-ink);
}
section[data-world="crimson"]::before {
  background:
    radial-gradient(80% 70% at 85% 10%, rgba(255,120,100,0.22), transparent 70%),
    radial-gradient(70% 80% at 0% 100%, rgba(20,0,0,0.45), transparent 70%),
    var(--grain), #8B0000;
  background-size: auto, auto, 220px 220px, auto;
  /* opens like slatted blinds as it comes up the screen */
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 calc(var(--wp) * 72px), transparent calc(var(--wp) * 72px) 72px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 calc(var(--wp) * 72px), transparent calc(var(--wp) * 72px) 72px);
}
section[data-world="crimson"] .btn { background: #FFF6F2; color: #7A0000; }
section[data-world="crimson"] .label, section[data-world="crimson"] .red { color: #FFD9D2; }
section[data-world="crimson"] :focus-visible { outline-color: #FFFFFF; }

/* ---- blueprint: navy ink with a drafting grid; the grid draws down the section and a crimson
   dimension line runs across the top, ticks at both ends */
section[data-world="blueprint"] {
  --sc-canvas: #0D1624; --sc-surface: #132036;
  --sc-ink: #EEF2F8; --sc-ink-soft: #A9B6CA; --sc-accent: #FF6B5E; --sc-accent-ink: #0D1624;
  --sc-shadow-color: 220 50% 4%;
  color: var(--sc-ink);
}
section[data-world="blueprint"]::before {
  background:
    linear-gradient(rgba(150,180,220,0.16) 1px, transparent 1px) 0 0 / 120px 120px,
    linear-gradient(90deg, rgba(150,180,220,0.16) 1px, transparent 1px) 0 0 / 120px 120px,
    linear-gradient(rgba(150,180,220,0.07) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, rgba(150,180,220,0.07) 1px, transparent 1px) 0 0 / 24px 24px,
    radial-gradient(90% 70% at 50% 0%, #16253C, #0D1624 70%);
  -webkit-mask-image: linear-gradient(#000 calc(var(--wp) * 120% - 20%), rgba(0,0,0,0.25) calc(var(--wp) * 120%));
  mask-image: linear-gradient(#000 calc(var(--wp) * 120% - 20%), rgba(0,0,0,0.25) calc(var(--wp) * 120%));
}
section[data-world="blueprint"]::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: var(--sc-gutter, 24px); right: var(--sc-gutter, 24px); top: calc(var(--bar-h) + 16px); height: 11px;
  background:
    linear-gradient(#FF6B5E, #FF6B5E) 0 50% / 100% 1px no-repeat,
    linear-gradient(#FF6B5E, #FF6B5E) 0 0 / 1px 100% no-repeat,
    linear-gradient(#FF6B5E, #FF6B5E) 100% 0 / 1px 100% no-repeat;
  transform-origin: left center; transform: scaleX(var(--wp));
  opacity: 0.8;
}

/* ---- steel: cool brushed grey; its cards and rows arrive by stacking up out of the floor,
   each a beat after the last, tipped a touch and settling flat */
section[data-world="steel"] {
  --sc-canvas: #D5D9DF; --sc-surface: #F4F5F7;
  --sc-ink: #111418; --sc-ink-soft: #454C57; --sc-accent: var(--brand); --sc-accent-ink: #FFFFFF;
  --sc-shadow-color: 215 20% 25%;
  color: var(--sc-ink);
}
section[data-world="steel"]::before {
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.22) 0 1px, transparent 1px 3px, rgba(0,0,0,0.035) 3px 4px),
    linear-gradient(100deg, #C7CCD3 0%, #E3E6EA 38%, #CDD2D9 62%, #DDE0E5 100%);
}
.js section[data-world="steel"] .stk {
  transform: translateY(calc((1 - var(--sk, 1)) * 70px)) rotate(calc((1 - var(--sk, 1)) * -2.2deg)) scale(calc(0.96 + var(--sk, 1) * 0.04));
  box-shadow: 0 calc(var(--sk, 1) * 18px) 38px -22px hsl(var(--sc-shadow-color) / 0.55);
  will-change: transform;
}

/* ---- circuit: near-black board; copper-red traces run across it and light up as it scrolls */
section[data-world="circuit"] {
  --sc-canvas: #0A0A0B; --sc-surface: #141416;
  --sc-ink: #F3F1EE; --sc-ink-soft: #ABA7A2; --sc-accent: #FF5A4E; --sc-accent-ink: #0A0A0B;
  --sc-shadow-color: 0 0% 2%;
  color: var(--sc-ink);
}
section[data-world="circuit"]::before {
  background:
    radial-gradient(70% 60% at 50% 50%, rgba(139,0,0,0.14), transparent 70%),
    radial-gradient(rgba(255,255,255,0.05) 1px, transparent 1.5px) 0 0 / 18px 18px,
    #0A0A0B;
}
.world__fx svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.trace { fill: none; stroke: #8B0000; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: 0.55; }
.trace--lit { stroke: #FF5A4E; stroke-width: 2; opacity: 0.6; filter: drop-shadow(0 0 4px rgba(255,90,78,0.6)); }
.pad { fill: #0A0A0B; stroke: #FF5A4E; stroke-width: 2; opacity: 0.8; }

/* ---- ticker: black, a band of huge outlined words sliding sideways with the scroll */
section[data-world="ticker"] {
  --sc-canvas: #050506; --sc-surface: #121214;
  --sc-ink: #F6F4F1; --sc-ink-soft: #ADA9A4; --sc-accent: #FF5A4E; --sc-accent-ink: #050506;
  --sc-shadow-color: 0 0% 2%;
  color: var(--sc-ink);
  padding-top: clamp(150px, 26vh, 260px);
}
section[data-world="ticker"]::before { background: linear-gradient(#050506, #0B0B0D); }
.ticker { position: absolute; left: 0; right: 0; top: clamp(20px, 5vh, 56px); z-index: -1; overflow: hidden; pointer-events: none; }
.ticker__row {
  display: flex; gap: 0.5em; width: max-content; white-space: nowrap;
  font-family: var(--sc-font-display); font-stretch: var(--wide); font-weight: 800;
  font-size: clamp(4.5rem, 2rem + 9vw, 11rem); line-height: 1; letter-spacing: -0.03em; text-transform: uppercase;
  color: transparent; -webkit-text-stroke: 1.5px rgba(246,244,241,0.28);
}
.ticker__row span:nth-child(3n + 2) { color: #5E0000; -webkit-text-stroke: 0; }

/* ---- spotlight: a dark wall of fine hatching, lit by a torch where the pointer is (on a touch
   screen the light walks across with the scroll) */
section[data-world="spotlight"] {
  --sc-canvas: #0B0C0E; --sc-surface: #16181C;
  --sc-ink: #F4F2EF; --sc-ink-soft: #AEAAA5; --sc-accent: #FF5A4E; --sc-accent-ink: #0B0C0E;
  --sc-shadow-color: 220 30% 3%;
  color: var(--sc-ink);
  --mx: 50%; --my: 45%;
}
section[data-world="spotlight"]::before {
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,0.06) 0 1px, transparent 1px 9px),
    #0B0C0E;
}
section[data-world="spotlight"] .world__fx {
  background:
    radial-gradient(circle at var(--mx) var(--my), rgba(255,236,220,0.30), rgba(139,0,0,0.22) 26%, transparent 50%),
    repeating-linear-gradient(135deg, rgba(255,255,255,0.16) 0 1px, transparent 1px 9px);
  -webkit-mask-image: radial-gradient(circle at var(--mx) var(--my), #000 0, rgba(0,0,0,0.6) 16%, transparent 38%);
  mask-image: radial-gradient(circle at var(--mx) var(--my), #000 0, rgba(0,0,0,0.6) 16%, transparent 38%);
}

/* ---- the About quote, three takes (prototype switcher, dev only; never deployed) */

@media (prefers-reduced-motion: reduce) {
  section[data-world] { --wp: 1 !important; }
  .ticker__row { transform: none !important; }
  .js section[data-world="steel"] .stk { transform: none !important; }
}
html.sc-failsafe section[data-world] { --wp: 1 !important; }
html.sc-failsafe section[data-world="steel"] .stk { transform: none !important; }
.trace--lit {
  stroke-dasharray: var(--len) var(--len);
  stroke-dashoffset: calc(var(--len) * (1 - clamp(0, (var(--q, 1) - var(--at, 0) * 0.5) * 2.2, 1)));
}
/* the home ledger keeps its own rise out of the hero; its paper does not wipe as well */
section[data-world][data-rise] { --wp: 1 !important; }

/* worlds: every colour the older sections take from the light ground follows
   the world instead (dark worlds had day-ink text on dark), white cards in a dark world keep their
   own dark text, pinned stages stop painting over their world, a hidden take stays hidden, and
   the traces stay in the margins */
section[data-world="crimson"], section[data-world="blueprint"], section[data-world="circuit"],
section[data-world="ticker"], section[data-world="spotlight"] {
  --day-ink: var(--sc-ink); --day-soft: var(--sc-ink-soft); --day-accent: var(--sc-accent);
}
section[data-world] .route:not(.route--dark) {
  --sc-ink: #121417; --sc-ink-soft: #4F5561; --sc-accent: var(--brand);
  --day-ink: #121417; --day-soft: #4F5561; --day-accent: var(--brand);
  color: #121417;
}
section[data-world="circuit"] .world__fx {
  -webkit-mask-image: linear-gradient(90deg, #000 0 8%, transparent 22% 78%, #000 92%);
  mask-image: linear-gradient(90deg, #000 0 8%, transparent 22% 78%, #000 92%);
}


    
  
 

/* ---- phones: each take as a plain, complete picture */

/* worlds: the circuit traces stay inside the gutters (never under the words),
   and none on a phone; the blueprint dimension line clears a phone heading */
section[data-world="circuit"] .world__fx {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(var(--sc-gutter) - 16px), transparent var(--sc-gutter), transparent calc(100% - var(--sc-gutter)), #000 calc(100% - var(--sc-gutter) + 16px));
  mask-image: linear-gradient(90deg, #000 0, #000 calc(var(--sc-gutter) - 16px), transparent var(--sc-gutter), transparent calc(100% - var(--sc-gutter)), #000 calc(100% - var(--sc-gutter) + 16px));
}
@media (max-width: 860px) {
  section[data-world="circuit"] .world__fx { display: none; }
  section[data-world="blueprint"].act-how { padding-top: calc(var(--bar-h) + 56px); }
}

/* ---- E: four steps ("the most simple version... explains the entire
   TradeSmart Systems business simply, as a workflow... premium"). A fine rail across the band;
   a soft crimson light runs along it and each step's dot lights as the light passes. */
/* ARRIVAL, one motion language ("a better animation... and a cooler
   animation for the actual copy... something that will still work on a phone"). A solid brand-red
   block sweeps across each headline line, uncovers the words, and sweeps off; the rule above fills
   red with it and stays; then the step rail draws and each step's title gets the same sweep as the
   rail reaches it, its dot filling red. Keyed to the arrival's own classes, CSS only: no script,
   reduced motion or the arrival's hard stop all show the finished page. */
.hero__h .ln__i { position: relative; }
@media (prefers-reduced-motion: no-preference) {
  /* the headline: no rise or blur here, the block does the arriving */
  .js .hero:has(> .hx:not([hidden])) .hero__h.is-split .ln__i { transform: none; opacity: 1; filter: none; transition: none; }
  .js .hero:has(> .hx:not([hidden])) .hero__h.is-split:not(.is-lit) .ln__i { color: transparent; }

   }

/* the glass behind the hero, quieter ("a little too intense on the eyes... a bit
   more subtle"): the canvas is laid over the plain dark ground at part strength */
.bgfx--night { opacity: 0.45; }

/* ARRIVAL, take 2: no block.
   Each headline line rises into focus, then one soft sheen of light passes across it; each step's
   title does the same as the rail reaches it. Text painted through its own gradient only while
   motion is allowed and the script has split it; otherwise plain ink. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero:has(> .hx:not([hidden])) .hero__h.is-lit .ln__i {
    background: linear-gradient(100deg, var(--night-ink) 40%, #FFFFFF 47%, #FFE3DD 50%, #FFFFFF 53%, var(--night-ink) 60%) 100% 0 / 300% 100% no-repeat;
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  .js .hero:has(> .hx:not([hidden])) .hero__h.is-lit .ln__i { animation: sheen-rise 2s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--i, 0) * 150ms + 100ms) both; }
}
@keyframes sheen-rise {
  0% { transform: translateY(55%); opacity: 0; filter: blur(10px); background-position: 100% 0; }
  40% { transform: none; opacity: 1; filter: blur(0); background-position: 100% 0; }
  100% { transform: none; opacity: 1; filter: none; background-position: 0% 0; }
}

/* ARRIVAL, take 3: the headline's
   letters rise into focus one after another, then the line under it (quicker), then the buttons,
   then each step's title as the rail reaches it. Only when motion is allowed and the script has
   split them; the failsafe shows every letter. */
.wd { display: inline-block; white-space: nowrap; }
.lt { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .js [data-letters].is-split .lt {
    transition: transform 800ms cubic-bezier(0.16, 1, 0.3, 1), opacity 600ms ease, filter 800ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--ld, 0ms) + var(--i, 0) * var(--ls, 30ms));
  }
  .js [data-letters].is-split:not(.is-lit) .lt { transform: translateY(0.55em); opacity: 0; filter: blur(6px); }
  .hero__h[data-letters] { --ld: 150ms; --ls: 34ms; }
  .hero__sub[data-letters] { --ld: 1500ms; --ls: 8ms; }
  .hero:has(> .hx:not([hidden])) .actions.fade-up { --d: 2300ms; }
   }
.sc-failsafe .lt { transform: none !important; opacity: 1 !important; filter: none !important; }
/* the rule over the headline finishes as the last word of the hero lands: the
   fourth step's title ends about 5.1 s in on a desktop, about 4.1 s on a phone */
@media (prefers-reduced-motion: no-preference) and (max-width: 860px) {
  .js .hero:not(.is-arriving):has(> .hx:not([hidden])) .hero__copy::before {
    animation: rule-in 0.9s var(--ease-io) 0.05s both, rule-load 3.95s cubic-bezier(0.37, 0, 0.63, 1) 0.15s both;
  }
}

/* worlds -------------------------------------------------------------
   the ticker bands run on their own at a reading pace (site.js sets the pace), not with the scroll */
@media (prefers-reduced-motion: no-preference) {
  .ticker__row { animation: tick 60s linear infinite; }
  .ticker--rev .ticker__row { animation-direction: reverse; }
}
@keyframes tick { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* each world brings its content in its own way, so no two sections in a row arrive alike */
@media (prefers-reduced-motion: no-preference) {
  .js section[data-world="paper"] [data-sc-in], .js section[data-world="paper"] [data-sc-stagger] > * { transform: translate3d(-44px, 0, 0); filter: none; }
  .js section[data-world="crimson"] [data-sc-in], .js section[data-world="crimson"] [data-sc-stagger] > * { transform: scale(0.95); filter: none; }
  .js section[data-world="blueprint"] [data-sc-in], .js section[data-world="blueprint"] [data-sc-stagger] > * { transform: none; filter: none; clip-path: inset(0 0 100% 0); transition: opacity 900ms ease, clip-path 1100ms cubic-bezier(0.65, 0, 0.35, 1); }
  .js section[data-world="steel"] [data-sc-in], .js section[data-world="steel"] [data-sc-stagger] > * { transform: translate3d(0, 46px, 0) rotate(-1.2deg); filter: none; }
  .js section[data-world="circuit"] [data-sc-in], .js section[data-world="circuit"] [data-sc-stagger] > * { transform: none; filter: blur(14px); }
  .js section[data-world="ticker"] [data-sc-in], .js section[data-world="ticker"] [data-sc-stagger] > * { transform: translate3d(48px, 0, 0); filter: none; }
  .js section[data-world="spotlight"] [data-sc-in], .js section[data-world="spotlight"] [data-sc-stagger] > * { transform: scale(1.05); filter: blur(8px); }
  .js section[data-world] [data-sc-in].sc-in, .js section[data-world] [data-sc-stagger] > .sc-in { transform: none; filter: none; clip-path: inset(0); }
  .js section[data-world] [data-sc-in][data-sc-stagger] { transform: none; filter: none; clip-path: none; }
}

/* home hero, twice as quick after the headline */
@media (prefers-reduced-motion: no-preference) {
  .js [data-letters].is-split:not(.hero__h) .lt { transition-duration: 450ms, 350ms, 450ms; }
  .hero__sub[data-letters] { --ld: 1250ms; --ls: 4ms; }
  .hero:has(> .hx:not([hidden])) .actions.fade-up { --d: 1500ms; }
     .js .hero:not(.is-arriving):has(> .hx:not([hidden])) .hero__copy::before {
    animation: rule-in 0.9s var(--ease-io) 0.05s both, rule-load 2.8s cubic-bezier(0.37, 0, 0.63, 1) 0.15s both;
  }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 860px) {
     .js .hero:not(.is-arriving):has(> .hx:not([hidden])) .hero__copy::before {
    animation: rule-in 0.9s var(--ease-io) 0.05s both, rule-load 2.3s cubic-bezier(0.37, 0, 0.63, 1) 0.15s both;
  }
}

/* the drawn sketches (the app on /tradesmart/, the kit on /starter-package/) in a dark world: a
   blueprint drawing, dark panels and light linework, instead of white panels that read as an empty box */
section[data-world="blueprint"] :is(.dash, .kit) .fl, section[data-world="circuit"] :is(.dash, .kit) .fl,
section[data-world="ticker"] :is(.dash, .kit) .fl, section[data-world="spotlight"] :is(.dash, .kit) .fl,
section[data-world="crimson"] :is(.dash, .kit) .fl { fill: rgba(22, 37, 62, 0.92); }
section[data-world="blueprint"] :is(.dash, .kit) .ln { stroke: rgba(214, 226, 244, 0.85); }
section[data-world="blueprint"] :is(.dash, .kit) .ln--soft { stroke: rgba(170, 190, 220, 0.5); }
section[data-world="blueprint"] :is(.dash, .kit) .ln--acc { stroke: #FF6B5E; }

/* the apprentices section as a logbook page ("formatted weirdly... make it look
   different"): no dark card. Heading and the goal on the left; on the right the four points are a
   checklist on ruled paper with a red margin line, each box ticking itself as its row arrives. */
.appr__panel {
  background: none; box-shadow: none; border-radius: 0; padding: 0;
  --sc-ink: #15130F; --sc-ink-soft: #57524A; --sc-accent: var(--brand); color: #15130F;
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(32px, 6vw, 110px); align-items: start;
}
.appr__head { grid-column: 1; grid-row: 1; }
.appr__goal { grid-column: 1; grid-row: 2; align-self: start; color: #15130F; border-top: 0; padding-top: 0; max-width: 16em;
  position: relative; padding-left: 44px; }
.appr__goal::before { content: ""; position: absolute; left: 4px; top: 0.25em; width: 12px; height: 22px;
  border: solid #8B0000; border-width: 0 4px 4px 0; transform: rotate(40deg); }
.appr__list {
  grid-column: 2; grid-row: 1 / span 2; margin: 0; grid-template-columns: 1fr; gap: 0;
  padding: 18px 0 18px 64px; position: relative; border-radius: 6px;
  background:
    linear-gradient(90deg, transparent 47px, rgba(139,0,0,0.55) 47px 49px, transparent 49px),
    repeating-linear-gradient(to bottom, transparent 0 35px, rgba(60,90,140,0.16) 35px 36px),
    #F7F4EE;
  box-shadow: 0 1px 0 rgba(0,0,0,0.05), 0 24px 50px -30px rgba(40,30,20,0.35);
}
.appr__item { border-top: 0; padding: 18px 20px 20px 0; }
.appr__item + .appr__item { border-top: 1px dashed rgba(21,19,15,0.14); }
.appr__item::before {
  left: -46px; top: 22px; width: 22px; height: 22px; background: #FFFFFF;
  border: 1.5px solid rgba(21,19,15,0.55); border-radius: 4px; box-sizing: border-box;
}
.appr__item::after {
  content: ""; position: absolute; left: -39px; top: 25px; width: 7px; height: 13px;
  border: solid #8B0000; border-width: 0 3px 3px 0; transform: rotate(40deg) scale(1); transform-origin: 50% 60%;
}
.appr__t { color: #15130F; }
.appr__d { color: #57524A; max-width: 34em; }
@media (prefers-reduced-motion: no-preference) {
  .js .appr__item::after { transform: rotate(40deg) scale(0); transition: transform 380ms cubic-bezier(0.34, 1.56, 0.64, 1) 420ms; }
  .js .appr__item.sc-in::after { transform: rotate(40deg) scale(1); }
}
@media (max-width: 860px) {
  .appr__panel { grid-template-columns: 1fr; row-gap: 32px; padding: 0; }
  .appr__head, .appr__list, .appr__goal { grid-column: 1; grid-row: auto; }
  .appr__goal { order: 3; }
  .appr__list { padding-left: 56px; background:
    linear-gradient(90deg, transparent 39px, rgba(139,0,0,0.55) 39px 41px, transparent 41px),
    repeating-linear-gradient(to bottom, transparent 0 35px, rgba(60,90,140,0.16) 35px 36px), #F7F4EE; }
  .appr__item::before { left: -44px; } .appr__item::after { left: -37px; }
}

/* a feature list with an odd count ends on a full-width row, so the last one never sits alone
   under an empty column */
@media (min-width: 861px) {
  .feats > .feat:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .feats > .feat:last-child:nth-child(odd) .feat__d { max-width: 44em; }
}

/* a world's ground and its content arrive TOGETHER ("I don't want the section to be
   there before the actual background is... slide on at the same time"): the paper's slanted wipe,
   the crimson's slats and the blueprint's unrolling now shape the whole section, words included,
   not only the ground behind them */
section[data-world="paper"]::before, section[data-world="crimson"]::before, section[data-world="blueprint"]::before {
  clip-path: none; -webkit-mask-image: none; mask-image: none;
}
section[data-world="paper"] {
  clip-path: polygon(0 0, calc(var(--wp) * 260%) 0, calc(var(--wp) * 260% - 30%) 100%, 0 100%);
}
section[data-world="crimson"] {
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 calc(var(--wp) * 72px), transparent calc(var(--wp) * 72px) 72px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 calc(var(--wp) * 72px), transparent calc(var(--wp) * 72px) 72px);
}
section[data-world="blueprint"] {
  -webkit-mask-image: linear-gradient(#000 calc(var(--wp) * 120% - 20%), rgba(0,0,0,0) calc(var(--wp) * 120%));
  mask-image: linear-gradient(#000 calc(var(--wp) * 120% - 20%), rgba(0,0,0,0) calc(var(--wp) * 120%));
}
/* the content's own entrance in these worlds would now double up with the reveal: it rides the reveal instead */
@media (prefers-reduced-motion: no-preference) {
  .js section[data-world="paper"] [data-sc-in], .js section[data-world="paper"] [data-sc-stagger] > *,
  .js section[data-world="crimson"] [data-sc-in], .js section[data-world="crimson"] [data-sc-stagger] > *,
  .js section[data-world="blueprint"] [data-sc-in], .js section[data-world="blueprint"] [data-sc-stagger] > * {
    opacity: 1; transform: none; filter: none; clip-path: none; transition: none;
  }
}

/* TradeSmart page --------------------------------------------
   The whole life of a job: calm dark ground (the grid made it hard to read) and no sliding app
   sketch down the side ("doesn't really move smoothly"); the stages read as a plain list. */
.life-sec .life__rail { display: none !important; }
@media (min-width: 981px) and (min-height: 760px) and (prefers-reduced-motion: no-preference) {
  .js .life-sec .life .stage__head { padding-top: 0; }
  .js .life-sec .life .stage__head::before { top: -5px; }
  .js .life-sec .life .stage__head::after { top: 2px; }
}
/* Apprentices: the heading fits its column, the goal runs full width under both columns at a
   readable size, and the section has room at the bottom */
.appr { padding-bottom: clamp(90px, 13vh, 160px); }
.appr__head .display { font-size: clamp(2rem, 0.9rem + 2.7vw, 3.6rem); max-width: none; }
.appr__goal {
  grid-column: 1 / -1; grid-row: 3; max-width: 34em; margin-top: clamp(40px, 7vh, 72px);
  font-size: clamp(1.25rem, 0.95rem + 0.9vw, 1.75rem); line-height: 1.3;
}
.appr__list { grid-row: 1 / span 1; }
/* Where it's heading: room at the bottom so the section never ends on its words */
.heading { padding-bottom: clamp(90px, 13vh, 160px); }
@media (max-width: 860px) {
  .appr__head, .appr__list, .appr__goal { grid-column: 1; grid-row: auto; }
}

/* crimson, take 3 ("red-striped and then it goes to black-on-white text...
   red on white is harder to read"). The section arrives as solid brand red; as it comes up the
   screen the red splits into stripes that thin away over a clean white section with dark text.
   The red is a layer ON TOP of the section, so nothing shows through half-drawn stripes. At
   rest (and with no script or reduced motion, --wp 1) it is simply white with dark ink. */
section[data-world="crimson"] {
  -webkit-mask-image: none; mask-image: none;
  --sc-canvas: #FFFFFF; --sc-surface: #F4F5F7;
  --sc-ink: #121417; --sc-ink-soft: #4F5561; --sc-accent: var(--brand); --sc-accent-ink: #FFFFFF;
  --day-ink: #121417; --day-soft: #4F5561; --day-accent: var(--brand);
  --sc-shadow-color: 220 18% 30%;
  color: #121417;
}
section[data-world="crimson"]::before {
  background: linear-gradient(#FFFFFF, #FAFAFB); border-top: 4px solid #8B0000;
  -webkit-mask-image: none; mask-image: none; clip-path: none;
}
section[data-world="crimson"]::after {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: repeating-linear-gradient(to bottom, #8B0000 0 calc((1 - var(--wp)) * 72px), transparent calc((1 - var(--wp)) * 72px) 72px);
}
section[data-world="crimson"] .btn { background: var(--brand); color: #FFFFFF; }
section[data-world="crimson"] .label { color: var(--sc-ink-soft); }
section[data-world="crimson"] .red { color: var(--brand); }
section[data-world="crimson"] :focus-visible { outline-color: var(--brand); }

/* crimson, take 4: SHUTTERS ("they came flat, then they opened sort of like
   shutters, then turned around and became the actual section"). site.js adds .shut with one slat
   per 72px; each slat's front is brand red, its back is the section's own ground, and it turns
   over (rotateX 0 -> 180deg) as the section comes up, top slat first. The words fade in as the
   last slats land. Without the script (no .shut) the section is simply its finished ground. */
section[data-world="crimson"]::after { content: none; }
.shut { position: absolute; inset: 0; z-index: -1; display: flex; flex-direction: column; perspective: 1400px; pointer-events: none; overflow: hidden; }
/* the premium finish: satin red with a fine lit edge, each slat
   shading as it turns edge-on and brightening as it lands, and the gaps between the turning slats
   open onto shadow that lifts as the shutter opens */
.shut { background: rgba(6, 4, 4, calc((1 - var(--wp)) * 0.85)); }

/* crimson, take 5: THE SECTION IS THE SHUTTER. While it arrives, the real
   content is hidden and .blinds shows slats of a finished copy; each slat turns from its red back
   (180deg) to its white face (0) as --wp rises, top slat first, shading as it turns edge-on. Gaps
   between turning slats show the page behind. At rest the real section is shown and the copy
   hidden. No script or reduced motion: no blinds, the finished white section. */
.shut { display: none !important; }
.blinds { display: none; position: absolute; inset: 0; z-index: 6; perspective: 1800px; pointer-events: none; }
section.blinds-on > .blinds { display: block; }
section.blinds-on > :not(.blinds) { visibility: hidden; }
section.blinds-on::before { opacity: 0; }
.blind {
  --fp: clamp(0, calc((var(--wp) - var(--k) * 0.45) / 0.55), 1);
  position: absolute; left: 0; right: 0; transform-style: preserve-3d;
  transform: rotateX(calc((1 - var(--fp)) * 180deg));
  filter: brightness(calc(1 - min(var(--fp), 1 - var(--fp)) * 0.9));
}
.blind::before {
  content: ""; position: absolute; inset: 0; transform: rotateX(180deg); backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.14) 0, rgba(255,255,255,0) 22%, rgba(0,0,0,0) 70%, rgba(0,0,0,0.3) 100%),
    linear-gradient(100deg, #6E0000 0%, #A10E0E 38%, #8B0000 62%, #6A0000 100%);
  box-shadow: inset 0 1px 0 rgba(255,210,200,0.3), inset 0 -1px 0 rgba(0,0,0,0.45);
}
.blind__f { position: absolute; inset: 0; overflow: hidden; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.blind__f > section { position: absolute; left: 0; right: 0; margin: 0; visibility: visible; }
.blind__f > section > * { visibility: visible; }
@media (prefers-reduced-motion: reduce) { .blinds { display: none !important; } section.blinds-on > :not(.blinds) { visibility: visible; } section.blinds-on::before { opacity: 1; } }
html.sc-failsafe .blinds { display: none !important; }
html.sc-failsafe section.blinds-on > :not(.blinds) { visibility: visible; }

/* blueprint: no red dimension line (it ran through the Who we are heading) */
section[data-world="blueprint"]::after { content: none; }
/* a filter on the turning slat flattens its 3D (the backs never hide), so the shading lives on each face */
.blind { filter: none; }
.blind__f, .blind::before { filter: brightness(calc(1 - min(var(--fp), 1 - var(--fp)) * 0.9)); }




/* closed shutter reads as ONE plain red section ("no lines to make it look like
   shutters"): every slat back is the same flat brand red with the fine grain, no per-slat shading
   or edge lines, and the slats overlap by a pixel so no seam shows. Only once they start turning
   do they read as slats. */
.blind::before {
  inset: -1px 0;
  background: var(--grain), #8B0000; background-size: 220px 220px, auto;
  box-shadow: none;
}


/* About quote, take A: marker underline. Off-white, big dark type; as it arrives a red marker
   stroke draws under "don't know where to start", like marking up a job sheet */
.mq { position: relative; isolation: isolate; padding: clamp(100px, 16vh, 190px) 0; color: #15130F;
  background: radial-gradient(90% 80% at 15% 0%, #FFFFFF, #F1EEE8 70%);
  --sc-ink: #15130F; --sc-ink-soft: #57524A; --sc-accent: var(--brand); }



/* circuit world without the edge traces ("the orange lines on the edges... look
   strange"): the fine dot field stays, and a soft crimson glow behind the content slowly breathes */
section[data-world="circuit"] .world__fx { display: none !important; }
section[data-world="circuit"]::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(55% 45% at 50% 55%, rgba(139, 0, 0, 0.26), transparent 72%);
}
@media (prefers-reduced-motion: no-preference) {
  section[data-world="circuit"]::after { animation: breathe 7s ease-in-out infinite; }
}
@keyframes breathe { 0%, 100% { opacity: 0.55; transform: scale(0.96); } 50% { opacity: 1; transform: scale(1.04); } }

/* spotlight world replaced: no hatching, no torch.
   A red horizon: black at the top, a low crimson glow along the foot, a thin lit line at its heart,
   a fine grain over it all. Same name, so every section using it changes at once. */
section[data-world="spotlight"] .world__fx { display: none !important; }
section[data-world="spotlight"]::before {
  background:
    radial-gradient(70% 55% at 50% 118%, rgba(200, 30, 20, 0.55), rgba(139, 0, 0, 0.28) 38%, transparent 72%),
    linear-gradient(180deg, #08090B 0%, #0C0D10 55%, #1A0707 100%);
}
section[data-world="spotlight"]::after {
  content: ""; position: absolute; left: 12%; right: 12%; bottom: 0; height: 1px; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 110, 90, 0.9), transparent);
  box-shadow: 0 0 24px 2px rgba(255, 70, 50, 0.45);
}
section[data-world="spotlight"]::before { background-image: var(--grain), radial-gradient(70% 55% at 50% 118%, rgba(200, 30, 20, 0.55), rgba(139, 0, 0, 0.28) 38%, transparent 72%), linear-gradient(180deg, #08090B 0%, #0C0D10 55%, #1A0707 100%); background-size: 220px 220px, auto, auto; }

/* the red horizon, animated. The glow rises
   into place as the section comes up (--wp), then drifts and breathes; faint sparks float up off
   the horizon and fade; a bright pulse runs along the lit line. All decoration, behind the words. */
section[data-world="spotlight"] .world__fx {
  display: block !important; -webkit-mask-image: none; mask-image: none;
  background: radial-gradient(45% 40% at 50% 100%, rgba(255, 70, 40, 0.38), rgba(139, 0, 0, 0.18) 45%, transparent 75%);
  transform: translateY(calc((1 - var(--wp, 1)) * 45%));
}
section[data-world="spotlight"] .world__fx::before,
section[data-world="spotlight"] .world__fx::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 200%;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 20%, rgba(255, 170, 120, 0.9), transparent),
    radial-gradient(1.2px 1.2px at 27% 65%, rgba(255, 140, 100, 0.8), transparent),
    radial-gradient(2px 2px at 41% 38%, rgba(255, 190, 140, 0.9), transparent),
    radial-gradient(1.3px 1.3px at 58% 82%, rgba(255, 150, 110, 0.8), transparent),
    radial-gradient(1.8px 1.8px at 71% 12%, rgba(255, 180, 130, 0.9), transparent),
    radial-gradient(1.2px 1.2px at 86% 55%, rgba(255, 140, 100, 0.8), transparent);
  background-size: 100% 50%;
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.6) 25%, transparent 60%);
  mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.6) 25%, transparent 60%);
  opacity: 0;
}
section[data-world="spotlight"] .world__fx::after { background-position: 37% 0; transform: scaleX(-1); }
section[data-world="spotlight"]::after { background-size: 100% 100%; }
@media (prefers-reduced-motion: no-preference) {
  section[data-world="spotlight"] .world__fx { animation: horizon-drift 11s ease-in-out infinite alternate; }
  section[data-world="spotlight"] .world__fx::before { opacity: 1; animation: sparks-up 14s linear infinite; }
  section[data-world="spotlight"] .world__fx::after { opacity: 1; animation: sparks-up 19s linear infinite; }
  section[data-world="spotlight"]::after {
    background: linear-gradient(90deg, transparent 0%, rgba(255, 110, 90, 0.55) 30%, #FFD0C0 50%, rgba(255, 110, 90, 0.55) 70%, transparent 100%) 0 0 / 300% 100%;
    animation: line-pulse 6s ease-in-out infinite;
  }
}
@keyframes horizon-drift {
  0% { background-position: -6% 0; filter: brightness(0.85); }
  50% { filter: brightness(1.15); }
  100% { background-position: 6% 0; filter: brightness(0.9); }
}
@keyframes sparks-up { from { transform: translateY(0); } to { transform: translateY(50%); } }
@keyframes line-pulse { 0%, 15% { background-position: 100% 0; } 65%, 100% { background-position: 0% 0; } }
/* fix-ups: sparks travel UP and loop seamlessly (strip twice the height, anchored at the top,
   moving one tile), the fade lives on the layer itself so it stays put while they rise, and the
   glow is wider than the section so its drift actually moves */
section[data-world="spotlight"] .world__fx {
  background-size: 130% 100%; background-position: 50% 0; background-repeat: no-repeat;
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 22%, transparent 80%);
  mask-image: linear-gradient(to top, #000 0%, #000 22%, transparent 80%);
}
section[data-world="spotlight"] .world__fx::before,
section[data-world="spotlight"] .world__fx::after { top: 0; bottom: auto; -webkit-mask-image: none; mask-image: none; }
@keyframes sparks-up { from { transform: translateY(0); } to { transform: translateY(-50%); } }
section[data-world="spotlight"] .world__fx::after { transform: none; }
@keyframes horizon-drift {
  0% { background-position: 35% 0; filter: brightness(0.85); }
  50% { filter: brightness(1.15); }
  100% { background-position: 65% 0; filter: brightness(0.9); }
}
/* no sparks (TradeSmart Systems is a software and AI company, not an electrical
   brand): the horizon keeps only its rise, its drift and the pulse along the lit line */
section[data-world="spotlight"] .world__fx::before,
section[data-world="spotlight"] .world__fx::after { content: none !important; animation: none !important; }

/* the horizon's motion made visible: the glow
   breathes (grows and settles) and drifts wide; a soft band of light rises up the section and fades */
@media (prefers-reduced-motion: no-preference) {
  section[data-world="spotlight"] .world__fx {
    -webkit-mask-image: none; mask-image: none;
    background: radial-gradient(50% 55% at 50% 100%, rgba(255, 80, 45, 0.5), rgba(139, 0, 0, 0.22) 45%, transparent 75%) no-repeat;
    animation: horizon-breathe 6s ease-in-out infinite, horizon-sway 14s ease-in-out infinite alternate !important;
  }
  section[data-world="spotlight"] .world__fx::before {
    content: "" !important; position: absolute; left: 0; right: 0; top: auto; bottom: 0; height: 22%;
    background: linear-gradient(180deg, transparent, rgba(255, 120, 95, 0.12) 50%, transparent);
    opacity: 1; animation: scan-rise 7s cubic-bezier(0.45, 0, 0.3, 1) infinite !important;
  }
}
@keyframes horizon-breathe {
  0%, 100% { background-size: 110% 70%; opacity: 0.75; }
  50% { background-size: 150% 115%; opacity: 1; }
}
@keyframes horizon-sway { from { background-position: 25% 100%; } to { background-position: 75% 100%; } }
@keyframes scan-rise {
  0% { transform: translateY(0); opacity: 0; }
  12% { opacity: 1; }
  70% { opacity: 0.6; }
  100% { transform: translateY(-420%); opacity: 0; }
}

/* closing section: the headline locks in. "Complimentary" shoots in
   from the left, "Discovery Call." from the right, they overshoot and snap together; the line fades
   up and the buttons pop. Plays once, when the section is well on screen (.is-played). */
section[data-world="spotlight"] .world__fx { animation: none !important; }
section[data-world="spotlight"] .world__fx::before { content: none !important; animation: none !important; }
section[data-world="spotlight"]::after { animation: none !important; }

/* the three "What you get" cards: the bottom
   line of every card sits level at the foot, and the reach card is a real four-row list */
.reach { list-style: none; margin: 18px 0 0; padding: 0; display: grid; }


/* the call timeline: each circle lights up solid red as the line reaches it (site.js sets is-lit
   from the line's own length); without the script every circle shows lit */
.beat::before { transition: background-color 220ms ease; }
.beats:not(.beats--live) .beat::before, .beat.is-lit::before { background: var(--day-accent); }

/* ---- unique sections: every page different between the header and the footer ---- */

/* About: How we work. Three big lines, each wiping in from the left as it comes up. */
.ways { padding: clamp(80px, 12vh, 150px) 0; }
.js section.ways [data-sc-in] { opacity: 1; transform: none; filter: none; clip-path: inset(0 100% 0 0);
  transition: clip-path 1000ms cubic-bezier(0.65, 0, 0.35, 1); }
.js section.ways [data-sc-in].sc-in { clip-path: inset(0 0 0 0); }

/* Starter Package: What you own. A job docket that prints down behind the red shutter; the stamp
   lands once it has printed. */
.own { text-align: center; }
.own .display { margin: 0 auto clamp(26px, 4vh, 44px); }

/* Home: the questions as a list with one big answer panel (desktop). Same details elements, so
   the answers stay in the page for search; phones keep the tap-to-open list. */
@media (min-width: 861px) {
  .faq--panel .faq__list { width: 44%; min-height: 420px; border-bottom: 0; }
  .faq--panel .faq__q::after { display: none; }
  @media (prefers-reduced-motion: no-preference) {
  }
}
.own h2.display--lg::after { margin-inline: auto; transform-origin: 50% 50%; }

/* ============================================================ PHONES
   A touch screen, or any screen 820px wide or less (the same query as film.js, site.js and the
   phone stills): nothing the GPU has to blur or blend over the whole page. A real Android phone
   could not keep up and painted the page in pieces. No backdrop blur anywhere (the bar and the
   panels get solid grounds instead), no page-to-page snapshot transition, and on the journey pages
   (plain pages on a phone, film.css) no fixed layer behind them: their own dark ground is it. */
@media (hover: none) and (pointer: coarse) and (max-aspect-ratio: 799/1000), (hover: none) and (pointer: coarse) and (min-aspect-ratio: 1351/1000), (max-width: 820px) {
  *, *::before, *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  .bar.is-scrolled { background: rgba(11,13,16,0.97); }
  [data-ground="day"] .bar { background: rgba(242,243,245,0.98); }
  @view-transition { navigation: none; }
  body:has(.main--film)::before, body:has(.main--film)::after { display: none; }

  /* the notch and the rounded corners (the page asks for viewport-fit=cover): the bar grows by the
     top inset and keeps its words clear of the sides; everything placed under the bar uses --sat */
  :root { --sat: env(safe-area-inset-top, 0px); }
  .bar { height: calc(var(--bar-h) + var(--sat)); padding-top: var(--sat);
    padding-left: max(var(--sc-gutter), env(safe-area-inset-left, 0px)); padding-right: max(var(--sc-gutter), env(safe-area-inset-right, 0px)); }
  .menu__panel { top: calc(var(--bar-h) + var(--sat)); height: calc(100vh - var(--bar-h) - var(--sat)); height: calc(100svh - var(--bar-h) - var(--sat));
    padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px)); }
  /* thumb-sized targets: 44px and up, the menu included */
  .menu > summary { min-height: 44px; min-width: 44px; justify-content: center; }
  /* one Book a call on a phone, at the bottom (the dock, below): the bar keeps the logo and the menu */
  .bar .btn--bar { display: none; }
  .menu__panel .btn { min-height: 52px; }

  /* the footer: every link a 44px row, the business details on their own lines */
  .foot__in { padding-inline-end: max(var(--sc-gutter), env(safe-area-inset-right, 0px)); padding-bottom: 36px; }
  .foot__brand { min-height: 44px; }
  .foot__nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; width: 100%; }
  .foot__nav a { display: flex; align-items: center; min-height: 44px; font-size: 1rem; }
  .foot__legal { flex-direction: column; gap: 0; font-size: 1rem; }
  .foot__legal .dot { display: none; }
  .foot__legal > span { padding: 3px 0; }
  .foot__legal a { display: inline-flex; align-items: center; min-height: 44px; overflow-wrap: anywhere; }

  /* the dock steps down whenever the footer is up, so the page needs no room kept under it; but
     anything brought into view (a link followed, a field focused, the keyboard's Tab) stops above it */
  html.has-dock { scroll-padding-bottom: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px) + 8px); }
}

/* ============================================================ THE DOCK
   Phones only (site.js initDock builds it on the same query as the rest of the phone version).
   One Book a call on a phone, at the bottom, without feeling stuck there. So the dock is a slim
   floating bar, inset from the edges, solid (no blur), above the
   home bar. It waits below the screen on the opening screen (the hero has its own Book a call),
   slides up once that button has scrolled away, and slides back down while another Book a call or
   the footer is on the screen, so there is only ever one in view. Transform only, about 250ms.
   The chat's round button sits at the bar's right end and does not move with it: while the bar is
   down it stays in the corner on its own, lifted (site.js, --chat-lift) just clear of any words. */
:root { --dock-h: 66px; --dock-end: max(12px, env(safe-area-inset-right, 0px)); --dock-low: calc(10px + env(safe-area-inset-bottom, 0px)); }
.dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 65; height: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px));
  pointer-events: none; }
html:has(.menu[open]) .dock, html:has(.menu[open]) .dock * { visibility: hidden; }
.dock__bar { position: absolute; left: max(12px, env(safe-area-inset-left, 0px)); right: var(--dock-end);
  bottom: var(--dock-low); height: 56px; display: flex; align-items: center; padding: 6px 58px 6px 6px; border-radius: 16px; pointer-events: auto;
  background: linear-gradient(180deg, #181B21, #0E1014);
  box-shadow: inset 0 0 0 1px rgba(242,240,237,0.09), inset 0 1px 0 rgba(255,255,255,0.07), 0 14px 30px -12px rgba(0,0,0,0.8), 0 2px 8px rgba(0,0,0,0.25);
  transform: translateY(calc(100% + var(--dock-low) + 24px)); visibility: hidden;
  transition: transform 220ms cubic-bezier(0.4, 0, 1, 1), visibility 0s linear 220ms; }
.dock.is-up .dock__bar { transform: none; visibility: visible; transition: transform 260ms var(--ease), visibility 0s; }
.dock--book-only .dock__bar { padding-right: 6px; }
.dock__book { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 16px; font-size: 1rem; box-shadow: inset 0 1px 0 rgba(255,255,255,0.14); }
.dock .chat__launch { position: absolute; right: calc(var(--dock-end) + 6px); bottom: calc(var(--dock-low) + 6px); width: 44px; height: 44px;
  pointer-events: auto; transform: translateY(calc(-1 * var(--chat-lift, 0px)));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 0 1.5px rgba(224,69,60,0.75), 0 6px 16px -6px rgba(0,0,0,0.7);
  transition: transform 260ms var(--ease), scale 140ms var(--ease); }
.dock .chat__mark { width: 36px; height: 36px; }
@media (prefers-reduced-motion: reduce) {
  .dock__bar, .dock.is-up .dock__bar, .dock .chat__launch { transition: none; }
}

/* the chat on a phone: the whole screen, like a messaging app, its close button top right and the
   page held still underneath (closing lands exactly where the reader was). site.js keeps the
   panel on the part of the screen the keyboard leaves (--vvh, --vvt from visualViewport). */
html.chat-full, html.chat-full body { overflow: hidden; }
.has-dock .chat__panel { position: fixed; inset: 0; top: var(--vvt, 0px); height: var(--vvh, auto); width: auto; max-height: none;
  border-radius: 0; background: var(--night); box-shadow: none;
  padding: var(--sat, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px); }
.has-dock .chat__panel:focus { outline: none; }
.has-dock .chat__head { min-height: 64px; padding: 8px 10px 8px 18px; }
.has-dock .chat__title { font-size: 1.1rem; }
.has-dock .chat__close { width: 48px; height: 48px; border-radius: 50%; background: rgba(242,240,237,0.08); color: var(--night-ink); }
.has-dock .chat__close svg { width: 20px; height: 20px; }
.has-dock .chat__log { min-height: 0; padding: 18px 16px 10px; }
.has-dock .chat__msg { font-size: 1rem; max-width: 88%; }
.has-dock .chat__book { min-height: 48px; font-size: 1rem; }
.has-dock .chat__note { font-size: 0.85rem; }
.has-dock .chat__form { padding: 10px 12px 12px; }
.has-dock .chat__input, .has-dock .chat__send { min-height: 52px; }
/* the smallest phones (320 wide): the bar's lockup, menu and Book a call all fit on one line */
@media (max-width: 359px) {
  .bar { padding-inline: 12px; gap: 8px; }
  .bar__end { gap: 6px; }
  .lockup-chrome { gap: 8px; --ms: 0.09; --ws: 0.2; }
  .lockup-day { gap: 8px; }
  .lockup-day__mark { height: 20px; }
  .lockup-day .wordmark__top { font-size: 1.05rem; }
  .lockup-day .wordmark__sub { font-size: 0.48rem; letter-spacing: 0.5em; margin-right: -0.5em; }
  .btn--bar { padding: 0 11px; font-size: 0.82rem; }
}

/* NO GLOW ANYWHERE: buttons keep only their edge highlight; status lights, timeline dots and the
   chat button keep crisp rings with no blurred coloured halo. */
.btn { box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 0 0 1px rgba(255,255,255,0.12); }
.led--build { box-shadow: none; }
@keyframes led { 50% { opacity: 0.35; } }
.step::before, .node::after, .stage__head::after { box-shadow: none; }
.chat__launch, .dock .chat__launch { box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 0 2px var(--brand), 0 12px 26px -8px rgba(0,0,0,0.6); }
@media (hover: hover) and (pointer: fine) {
  .chat__launch:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 0 2px var(--night-accent), 0 12px 26px -8px rgba(0,0,0,0.6); }
}
