/* ============================================================
   ZIRYVO — base
   Tokens, reset, typography scale, layout shell, reveal system.
   ============================================================ */

/* ---- Inter, self-hosted. latin-ext carries Hungarian ő / ű. ---- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.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: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.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;
}

/* Real italics — used by the About headline's second line. A synthetic
   oblique slants the uprights and reads cheap at display sizes. */
@font-face {
  font-family: 'Inter';
  font-style: italic;
  font-weight: 300 600;
  font-display: swap;
  src: url('../assets/fonts/inter-italic-latin-ext.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: 'Inter';
  font-style: italic;
  font-weight: 300 600;
  font-display: swap;
  src: url('../assets/fonts/inter-italic-latin.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;
}

/* Handwriting face for the lime accent words. Loaded for both Latin subsets
   so Hungarian accents are covered. */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../assets/fonts/caveat-latin-ext.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: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../assets/fonts/caveat-latin.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;
}

/* ---- Tokens ---- */
:root {
  --bg:          #000000;
  --fg:          #ffffff;

  /* The one accent. Used as punctuation, never as a surface. */
  --lime:        #b8ff3d;
  --lime-dim:    rgba(184, 255, 61, 0.72);
  --lime-faint:  rgba(184, 255, 61, 0.28);
  --fg-dim:      rgba(255, 255, 255, 0.62);
  --fg-soft:     rgba(255, 255, 255, 0.46);
  --fg-faint:    rgba(255, 255, 255, 0.30);
  --line:        rgba(255, 255, 255, 0.12);
  --line-soft:   rgba(255, 255, 255, 0.07);
  --surface:     rgba(255, 255, 255, 0.03);

  /* One easing curve across the whole site keeps the motion coherent. */
  --ease:        cubic-bezier(0.16, 1, 0.30, 1);
  --ease-soft:   cubic-bezier(0.33, 1, 0.68, 1);

  --shell:       1280px;
  --gut:         clamp(20px, 4vw, 40px);
  --nav-h:       72px;

  /* Vertical rhythm. Sections deliberately do NOT share one height —
     each picks a step to create the pacing the brief asks for. */
  --sp-xs:       clamp(44px, 5vw, 64px);
  --sp-sm:       clamp(60px, 6.5vw, 92px);
  --sp-md:       clamp(76px, 8.5vw, 124px);
  --sp-lg:       clamp(92px, 10.5vw, 156px);
  --sp-xl:       clamp(110px, 12.5vw, 190px);
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 24px);
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-feature-settings: 'cv11', 'ss01';
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* No overflow-x:hidden here. It computes to `hidden auto`, which turns body
     into a clipping container and shears the live-demo widget (position:fixed)
     mid-panel. Horizontal overflow is instead prevented at source — every wide
     element (hours marquee, waveform) is clipped by its own section. */
}

img, svg, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }

::selection { background: rgba(255, 255, 255, 0.18); color: #fff; }

:focus-visible {
  outline: 1px solid rgba(255, 255, 255, 0.55);
  outline-offset: 4px;
  border-radius: 2px;
}

/* ---- Layout ---- */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gut);
}
.shell--narrow { max-width: 980px; }

.section { position: relative; }

/* Hairline seams between bands, never a hard border. */
.section--ruled { border-top: 1px solid var(--line-soft); }

/* ---- Typography scale ------------------------------------------------
   The vh term on display sizes stops headlines from swallowing short
   laptop viewports.                                                     */
.t-display {
  font-size: clamp(2.9rem, min(9.2vw, 15.5vh), 8.6rem);
  line-height: 0.93;
  letter-spacing: -0.042em;
  font-weight: 600;
}
.t-h1 {
  font-size: clamp(2.3rem, 6.2vw, 5.2rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
  font-weight: 600;
}
.t-h2 {
  font-size: clamp(1.9rem, 4.4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 500;
}
.t-h3 {
  font-size: clamp(1.35rem, 2.4vw, 2rem);
  line-height: 1.18;
  letter-spacing: -0.022em;
  font-weight: 500;
}
.t-lead {
  font-size: clamp(1rem, 1.45vw, 1.25rem);
  line-height: 1.6;
  color: var(--fg-dim);
  font-weight: 400;
}
.t-body {
  font-size: clamp(0.94rem, 1.15vw, 1.05rem);
  line-height: 1.68;
  color: var(--fg-dim);
}
.t-small { font-size: 0.875rem; line-height: 1.6; color: var(--fg-soft); }

/* Section labels carry the accent — small, frequent, and the main reason the
   lime reads as systematic rather than decorative. */
.t-eyebrow {
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--lime);
  font-weight: 500;
}

/* A number/label set in tabular figures, used by process + workflow. */
.t-index {
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  color: var(--lime-dim);
}

/* ============================================================
   Handwritten accent
   A lime word set in Caveat, tilted off-axis and overlapping the
   headline above it. Revealed by sweeping a soft-edged mask across
   it, so it reads as being written rather than fading in.
   ============================================================ */
.ink {
  display: inline-block;
  font-family: 'Caveat', 'Segoe Script', cursive;
  font-weight: 700;
  color: var(--lime);
  letter-spacing: 0.005em;
  line-height: 0.86;
  /* Sits slightly over the line above it, like a note added afterwards. */
  transform: rotate(-2.6deg);
  transform-origin: left center;

  /* Mask is twice the element's width: opaque on its left, feathering to
     transparent. Sliding it from 100% to 0% uncovers the word left-to-right
     with a soft leading edge. */
  -webkit-mask-image: linear-gradient(to right, #000 44%, rgba(0,0,0,0.55) 50%, transparent 57%);
          mask-image: linear-gradient(to right, #000 44%, rgba(0,0,0,0.55) 50%, transparent 57%);
  -webkit-mask-size: 230% 100%;
          mask-size: 230% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: 100% 0;
          mask-position: 100% 0;

  transition:
    -webkit-mask-position 1.35s cubic-bezier(0.62, 0.03, 0.24, 1) var(--ink-delay, 0.45s),
            mask-position 1.35s cubic-bezier(0.62, 0.03, 0.24, 1) var(--ink-delay, 0.45s);
}
.ink.is-in {
  -webkit-mask-position: 0 0;
          mask-position: 0 0;
}

/* Display-scale handwriting, used where it replaces a headline line. */
.ink--display { font-size: clamp(3.2rem, min(11vw, 18vh), 10rem); }
/* Caveat has deep descenders and sits rotated; padding keeps both clear of
   any ancestor that clips. */
.ink { padding: 0.06em 0.12em 0.16em; }
/* Overlapping label under a section headline. */
.ink--label   { font-size: clamp(2rem, 5.4vw, 4.6rem); margin-top: -0.34em; }

@media (prefers-reduced-motion: reduce) {
  .ink {
    -webkit-mask-image: none;
            mask-image: none;
  }
}

.measure    { max-width: 62ch; }
.measure-sm { max-width: 46ch; }

/* ============================================================
   Reveal system
   Elements start hidden and are released by IntersectionObserver
   (js/reveal.js) adding .is-in. Everything animates transform +
   opacity only, so it stays on the compositor.
   ============================================================ */

/* Fade + rise ------------------------------------------------ */
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, var(--reveal-y, 26px), 0);
  transition:
    opacity 1.05s var(--ease) var(--reveal-delay, 0s),
    transform 1.05s var(--ease) var(--reveal-delay, 0s);
  will-change: transform, opacity;
}
[data-reveal].is-in {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
[data-reveal="fade"] { --reveal-y: 0px; }
[data-reveal="rise-lg"] { --reveal-y: 48px; }

/* Masked line reveal ----------------------------------------
   .reveal-lines wraps each line in an overflow:hidden box so the
   text slides up from behind its own edge, rather than fading.  */
.reveal-lines .rl {
  display: block;
  overflow: hidden;
  /* The mask has to clear descenders below and italic ascender overhang
     above, or overflow shears the tails off g/y/j and the tops off italic
     caps. The negative margins give the room back, so the extra space
     never shows up in the layout. The line is only ever hidden downward,
     so padding-top cannot let it peek early. */
  padding-top: 0.14em;
  margin-top: -0.14em;
  padding-bottom: 0.22em;
  margin-bottom: -0.22em;
}
.reveal-lines .rl > span {
  display: block;
  /* Must exceed 100% + the mask's padding, or the line peeks before it
     is released. */
  transform: translate3d(0, 132%, 0);
  transition: transform 1.15s var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms + var(--reveal-delay, 0s));
  will-change: transform;
}
.reveal-lines.is-in .rl > span { transform: translate3d(0, 0, 0); }

/* Staggered children ----------------------------------------- */
.stagger > * {
  opacity: 0;
  transform: translate3d(0, 24px, 0);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.stagger.is-in > * { opacity: 1; transform: none; }
.stagger.is-in > *:nth-child(1)  { transition-delay: 0.00s; }
.stagger.is-in > *:nth-child(2)  { transition-delay: 0.08s; }
.stagger.is-in > *:nth-child(3)  { transition-delay: 0.16s; }
.stagger.is-in > *:nth-child(4)  { transition-delay: 0.24s; }
.stagger.is-in > *:nth-child(5)  { transition-delay: 0.32s; }
.stagger.is-in > *:nth-child(6)  { transition-delay: 0.40s; }
.stagger.is-in > *:nth-child(7)  { transition-delay: 0.48s; }
.stagger.is-in > *:nth-child(8)  { transition-delay: 0.56s; }
.stagger.is-in > *:nth-child(9)  { transition-delay: 0.64s; }
.stagger.is-in > *:nth-child(10) { transition-delay: 0.72s; }

/* A hairline that draws itself in when its section arrives. */
.rule {
  height: 1px;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.4s var(--ease);
}
.rule.is-in { transform: scaleX(1); }

/* ---- Accessibility ---- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  [data-reveal],
  .stagger > *,
  .reveal-lines .rl > span {
    opacity: 1 !important;
    transform: none !important;
  }
  .rule { transform: scaleX(1) !important; }
}

/* Screen-reader only */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: 10px; left: 10px; z-index: 200;
  padding: 10px 18px; background: #fff; color: #000;
  border-radius: 100px; font-size: 0.85rem; font-weight: 500;
  transform: translateY(-160%);
  transition: transform 0.4s var(--ease);
}
.skip-link:focus { transform: none; }
