@import "tailwindcss";

/* ------------------------------------------------------------------ */
/* Design tokens — "Signal on Paper" (docs/03-visual-design-system.md) */
/* ------------------------------------------------------------------ */

@theme {
  --color-paper: #f4f2ed;
  --color-paper-deep: #eae6de;
  --color-surface: #fbfaf7;
  --color-ink: #101014;
  --color-ink-soft: #3b3b42;
  --color-muted: #5f5f67;
  --color-line: #dcd8cf;
  --color-line-strong: #86817a;
  --color-signal: #3326ff;
  --color-signal-deep: #2419d9;
  --color-signal-bright: #8f8aff;
  --color-signal-mist: #e7e6ff;
  --color-night: #0d0d11;
  --color-night-raised: #16161c;
  --color-night-line: #2b2b33;
  --color-night-text: #f4f2ed;
  --color-night-muted: #a3a2ac;
  --color-mist: #e6e6f1;
  --color-sand: #ede4d6;

  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.875rem;

  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-in-out-soft: cubic-bezier(0.65, 0, 0.35, 1);

  --text-display-xl: clamp(2.75rem, 1.1rem + 5.4vw, 5.5rem);
  --text-display-xl--line-height: 0.96;
  --text-display-xl--letter-spacing: -0.045em;
  --text-display-xl--font-weight: 500;

  --text-display-lg: clamp(2.35rem, 1.3rem + 3.6vw, 4.25rem);
  --text-display-lg--line-height: 1;
  --text-display-lg--letter-spacing: -0.04em;
  --text-display-lg--font-weight: 500;

  --text-display-md: clamp(1.9rem, 1.2rem + 2.2vw, 3.1rem);
  --text-display-md--line-height: 1.05;
  --text-display-md--letter-spacing: -0.035em;
  --text-display-md--font-weight: 500;

  --text-title: clamp(1.35rem, 1.1rem + 0.7vw, 1.75rem);
  --text-title--line-height: 1.15;
  --text-title--letter-spacing: -0.02em;
  --text-title--font-weight: 500;

  --text-lead: clamp(1.125rem, 1.02rem + 0.35vw, 1.3rem);
  --text-lead--line-height: 1.5;
  --text-lead--letter-spacing: -0.005em;

  --text-label: 0.75rem;
  --text-label--line-height: 1.2;
  --text-label--letter-spacing: 0.09em;
  --text-label--font-weight: 600;

  --text-data: 0.6875rem;
  --text-data--line-height: 1.3;
  --text-data--letter-spacing: 0.02em;
}

@theme inline {
  --font-sans: var(--font-schibsted), ui-sans-serif, system-ui, sans-serif;
  --font-serif: var(--font-newsreader), ui-serif, Georgia, serif;
  --font-mono: var(--font-plex-mono), ui-monospace, "SFMono-Regular", monospace;
}

/* ------------------------------------------------------------------ */
/* Base                                                                */
/* ------------------------------------------------------------------ */

@layer base {
  html {
    background-color: var(--color-paper);
    color: var(--color-ink);
    color-scheme: light;
    -webkit-text-size-adjust: 100%;
    scroll-padding-top: 6rem;
  }

  @media (prefers-reduced-motion: no-preference) {
    html {
      scroll-behavior: smooth;
    }
  }

  body {
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.62;
    font-kerning: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: clip;
  }

  @media (min-width: 64rem) {
    body {
      font-size: 1.0625rem;
    }
  }

  h1,
  h2,
  h3,
  h4 {
    text-wrap: balance;
  }

  p,
  li,
  dd {
    text-wrap: pretty;
  }

  ::selection {
    background-color: var(--color-signal-mist);
    color: var(--color-ink);
  }

  :focus-visible {
    outline: 2px solid var(--color-signal);
    outline-offset: 3px;
    border-radius: 2px;
  }

  .tone-night :focus-visible {
    outline-color: var(--color-signal-bright);
  }

  main:focus {
    outline: none;
  }

  summary {
    list-style: none;
  }

  summary::-webkit-details-marker {
    display: none;
  }
}

/* ------------------------------------------------------------------ */
/* Layout utilities                                                    */
/* ------------------------------------------------------------------ */

@utility container-page {
  width: 100%;
  max-width: 85rem;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 3rem);
}

@utility container-narrow {
  width: 100%;
  max-width: 48rem;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 3rem);
}

@utility section-space {
  padding-block: clamp(5rem, 3rem + 6vw, 9rem);
}

@utility section-space-tight {
  padding-block: clamp(3.5rem, 2.5rem + 4vw, 6rem);
}

@utility measure {
  max-width: 64ch;
}

@utility measure-lead {
  max-width: 46ch;
}

@utility font-numeric {
  font-variant-numeric: tabular-nums;
}

/* Subtle paper grain. Tile is rasterized once; never animated. */
@utility grain {
  position: relative;
  isolation: isolate;

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }
}

.tone-night.grain::before,
.tone-night .grain::before {
  opacity: 0.06;
  filter: invert(1);
}

/* ------------------------------------------------------------------ */
/* Motion: reveal-on-enter (RevealObserver adds .is-revealed)          */
/* ------------------------------------------------------------------ */

html.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 1.125rem, 0);
  transition:
    opacity 800ms var(--ease-out-expo),
    transform 900ms var(--ease-out-expo);
  transition-delay: var(--reveal-delay, 0ms);
}

html.js [data-reveal="fade"] {
  transform: none;
}

html.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* Hero headline: CSS-only line mask so the LCP text animates on first paint. */
.headline-line {
  display: block;
  overflow: hidden;
  padding: 0 0.12em 0.1em 0;
  margin: 0 -0.12em -0.1em 0;
}

.headline-line > span {
  display: block;
  animation: line-rise 1000ms var(--ease-out-expo) both;
  animation-delay: calc(var(--line-index, 0) * 90ms + 60ms);
}

@keyframes line-rise {
  from {
    transform: translate3d(0, 108%, 0);
  }
  to {
    transform: none;
  }
}

.fade-rise {
  animation: fade-rise 900ms var(--ease-out-expo) both;
  animation-delay: var(--delay, 0ms);
}

@keyframes fade-rise {
  from {
    opacity: 0;
    transform: translate3d(0, 0.75rem, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Underline that draws under the hero accent word. */
.accent-underline {
  background-image: linear-gradient(var(--color-signal), var(--color-signal));
  background-repeat: no-repeat;
  background-position: 0 92%;
  background-size: 0% 0.06em;
  animation: underline-draw 900ms var(--ease-out-expo) 950ms forwards;
}

@keyframes underline-draw {
  to {
    background-size: 100% 0.06em;
  }
}

/* SVG stroke drawing, triggered by .is-revealed on an ancestor. */
html.js [data-reveal] .draw-path {
  stroke-dasharray: var(--path-length, 1000);
  stroke-dashoffset: var(--path-length, 1000);
  transition: stroke-dashoffset 1400ms var(--ease-out-expo);
  transition-delay: calc(var(--reveal-delay, 0ms) + var(--draw-delay, 150ms));
}

html.js [data-reveal].is-revealed .draw-path {
  stroke-dashoffset: 0;
}

/* ------------------------------------------------------------------ */
/* Components                                                          */
/* ------------------------------------------------------------------ */

.btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition:
    color 320ms var(--ease-out-quart),
    border-color 320ms var(--ease-out-quart),
    background-color 320ms var(--ease-out-quart);
}

.btn-fill {
  position: absolute;
  left: var(--fill-x, 50%);
  top: var(--fill-y, 50%);
  z-index: -1;
  width: 260%;
  aspect-ratio: 1;
  border-radius: 9999px;
  background: var(--btn-fill, var(--color-ink));
  transform: translate(-50%, -50%) scale(0);
  transition: transform 520ms var(--ease-out-expo);
  pointer-events: none;
}

.btn:hover .btn-fill,
.btn:focus-visible .btn-fill {
  transform: translate(-50%, -50%) scale(1);
}

.btn-arrow {
  transition: transform 420ms var(--ease-out-expo);
}

.btn:hover .btn-arrow,
.btn:focus-visible .btn-arrow,
.link-arrow:hover .btn-arrow,
.link-arrow:focus-visible .btn-arrow,
.group:hover .btn-arrow {
  transform: translate3d(0.2rem, 0, 0);
}

.link-underline {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  padding-bottom: 0.15em;
  transition: background-size 420ms var(--ease-out-expo);
}

.link-underline-hover {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  padding-bottom: 0.15em;
  transition: background-size 420ms var(--ease-out-expo);
}

.link-underline-hover:hover,
.link-underline-hover:focus-visible,
.group:hover .link-underline-hover {
  background-size: 100% 1px;
}

/* FAQ accordion: native details with progressive height animation. */
.faq-item {
  interpolate-size: allow-keywords;
}

.faq-item::details-content {
  block-size: 0;
  overflow: clip;
  transition:
    block-size 420ms var(--ease-out-expo),
    content-visibility 420ms allow-discrete;
}

.faq-item[open]::details-content {
  block-size: auto;
}

.faq-icon line:last-child {
  transform-origin: center;
  transition: transform 320ms var(--ease-out-quart);
}

.faq-item[open] .faq-icon line:last-child {
  transform: rotate(90deg);
}

/* Signal particles in diagrams are ambient; hide them when motion is reduced. */
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal],
  html.js [data-reveal] .draw-path {
    opacity: 1;
    transform: none;
    transition: none;
    stroke-dashoffset: 0;
  }

  .headline-line > span,
  .fade-rise {
    animation: none;
  }

  .accent-underline {
    animation: none;
    background-size: 100% 0.06em;
  }

  .signal-particle {
    display: none;
  }

  .btn-fill,
  .btn-arrow,
  .link-underline-hover,
  .faq-item::details-content {
    transition: none;
  }
}

/* Horizontal scroll rows (mobile resource cards, metric chips). */
.scroll-row {
  scrollbar-width: none;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
}

.scroll-row::-webkit-scrollbar {
  display: none;
}

.scroll-row > * {
  scroll-snap-align: start;
}

/* Menus */
.menu-panel {
  animation: menu-in 460ms var(--ease-out-expo) both;
}

.mobile-sheet {
  animation: sheet-in 420ms var(--ease-out-expo) both;
}

/* Platform marquee: two rows drifting in opposite directions, paused on hover or focus.
   The set repeats --marquee-copies times and shifts by exactly one copy, so the loop never
   shows its seam and never runs out of pills. Spacing sits inside each copy, not in the
   track, so the gap across the seam matches every other gap. */
@keyframes marquee-drift {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(calc(-100% / var(--marquee-copies, 5)), 0, 0);
  }
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee-drift var(--marquee-duration, 60s) linear infinite;
  animation-delay: var(--marquee-delay, 0s);
}

.marquee-track[data-direction="right"] {
  animation-direction: reverse;
}

.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  /* No drift: the rows sit inside the page container, wrap, and drop the repeated copies. */
  .marquee {
    width: 100%;
    max-width: 85rem;
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
    mask-image: none;
  }

  .marquee-track {
    width: 100%;
    flex-wrap: wrap;
    animation: none;
  }

  .marquee-clone {
    display: none;
  }
}

@keyframes menu-in {
  from {
    opacity: 0;
    transform: translate3d(0, -0.375rem, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes sheet-in {
  from {
    opacity: 0;
    transform: translate3d(0, 0.75rem, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .menu-panel,
  .mobile-sheet {
    animation: none;
  }
}

/* Revenue Circuit: de-emphasize stages that aren't centered (desktop, JS only). */
@media (min-width: 64rem) {
  html.js .circuit-stage:not([data-active="true"]) {
    opacity: 0.62;
  }
}
