/* JUG.ba — DERIVED from designs/smoke/style.css, not a copy of it.
   Do NOT re-stamp the preset over this file and do not assume any region matches upstream:
   roughly 266 lines differ, and the differences are load-bearing. Diff before touching.

   Local and deliberate, above the adaptations banner as well as below it:
     · the whole twin-puff fog system (the preset had two static layers)
     · fog opacities 0.63/0.48/0.22 — tied to the contrast table in DESIGN.md
     · .hero-center::before, the scrim that is the only reason the hero passes AA
     · input[type=email] focus ring: the preset's bare `outline: none` outranked
       :focus-visible and left that one field with no keyboard focus indicator
     · hero gradient re-seeded to the Bosnian blue; .wordmark 400 -> 700
     · hero vertical padding 4vw -> 4.5vh, so the legal nav survives a short laptop
     · view transitions 1.2s asymmetric -> 200ms symmetric

   Consumes tokens only, except the hero background gradients and fog alphas, which are part
   of the identity per designs/smoke/DESIGN.md. */

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

body {
  margin: 0;
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-family: var(--font-family);
  font-weight: var(--font-weight-regular);
  font-size: 16.5px;
  line-height: 1.65;
}

a {
  color: inherit;
}

a:hover {
  color: var(--color-on-surface-strong);
}

::selection {
  background: var(--color-accent-border-strong);
}

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

p {
  margin: 0;
}

/* ---------- hero (shared) ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  background: radial-gradient(120% 90% at 50% 40%, #111a2e 0%, #0a1120 70%, #070a12 100%);
}

.hero-inner {
  position: relative;
  z-index: 1;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-xl);
  /* Vertical padding scales with viewport HEIGHT, not width. The preset used 4vw for both,
     which on a wide-but-short laptop screen (1440x760) spent 104px on padding and pushed the
     legal nav off the bottom — the hero is supposed to fit one screen. */
  padding: clamp(24px, 4.5vh, 52px) clamp(24px, 5vw, 72px);
}

/* 700, not regular: a serif wordmark holds its own at 400, a sans one just looks like body
   copy. Tracking stays slightly open so the dot in "JUG.ba" keeps room. */
.wordmark {
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-bold);
  font-size: 22px;
  letter-spacing: 0.02em;
  color: var(--color-on-surface-strong);
}

.mono,
.hero nav,
.consent {
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.mono {
  color: var(--color-on-surface-muted);
}

.hero-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--spacing-lg);
}

.hero nav {
  display: flex;
  justify-content: center;
  gap: 28px;
  color: var(--color-on-surface-meta);
}

/* ---------- fog: CSS re-expression of the source's canvas smoke ----------
   three declarative layers, all standards, no script:
   1. .fog--back  — soft gradient puffs behind the content
   2. .hero::after — real fractal-noise texture (SVG feTurbulence asset)
   3. .fog--front — puffs OVER the content, the "under wraps" veil
   mix-blend-mode: screen is the analog of the canvas globalCompositeOperation */

.fog {
  position: absolute;
  inset: -20%;
  pointer-events: none;
  mix-blend-mode: screen;
}

/* Each fog layer paints nothing itself: it is a constant-opacity group holding TWIN copies
   of its puff set (::before and ::after) running the same emanation half a cycle apart.
   A triangular 0->1->0 opacity envelope summed with itself at 50% offset is exactly
   constant, so the layer's density never dips — puffs emerge from the centre while the
   previous set is still dissipating outward. The puff set lives in --puffs so both twins
   share one definition. */
/* The twins carry DIFFERENT puff sets (--puffs-a / --puffs-b). With identical sets you see
   every puff at two radii at once, converging and diverging as the cycle turns, which reads
   as the fog pulsing inward and outward. Decorrelated sets remove any paired positions, so
   what you see is a continuous stream of puffs emerging near the centre and sweeping out. */
.fog::before,
.fog::after {
  content: '';
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  pointer-events: none;
}

.fog::before {
  background-image: var(--puffs-a);
}

.fog::after {
  background-image: var(--puffs-b);
}

/* ::before carries the layer on its own when animation is off, so a reduced-motion still
   frame shows exactly one puff set — the density the contrast table was computed against.
   Two visible copies would stack to a higher alpha than that table allows. */
.fog::before {
  opacity: 1;
}

.fog::after {
  opacity: 0;
}

/* Layer opacity is now CONSTANT (the twins handle the fading), and each value is the
   maximum the DESIGN.md contrast table was computed against. */
/* Puffs sit near the middle of the layer so that scaling sweeps them outward from behind the
   statement block — the further a puff is from the layer centre, the further scaling throws
   it, so centre-biased positions read as radiating from the text rather than sliding past it. */
.fog--back {
  z-index: 0;
  opacity: 0.63;
  --puffs-a:
    radial-gradient(40% 30% at 38% 44%, rgba(var(--fog-back), 0.34) 0%, transparent 70%),
    radial-gradient(34% 26% at 61% 53%, rgba(var(--fog-back), 0.26) 0%, transparent 70%),
    radial-gradient(46% 32% at 49% 63%, rgba(var(--fog-back), 0.22) 0%, transparent 72%);
  --puffs-b:
    radial-gradient(38% 28% at 57% 39%, rgba(var(--fog-back), 0.32) 0%, transparent 70%),
    radial-gradient(36% 27% at 40% 57%, rgba(var(--fog-back), 0.25) 0%, transparent 70%),
    radial-gradient(44% 31% at 62% 61%, rgba(var(--fog-back), 0.22) 0%, transparent 72%);
}

.fog--noise {
  z-index: 0;
  opacity: 0.22;
  --puffs-a: url('/images/fog-noise.svg');
  --puffs-b: url('/images/fog-noise.svg');
}

/* real fractal texture (SVG feTurbulence, stitched so it tiles) — the layer whose motion the
   eye can actually follow, which is why it emanates on the shortest cycle */
.fog--noise::before,
.fog--noise::after {
  background-size: 780px;
  background-repeat: repeat;
}

.fog--front {
  z-index: 2;
  opacity: 0.48;
  --puffs-a:
    radial-gradient(28% 21% at 59% 58%, rgba(var(--fog-front), 0.30) 0%, transparent 70%),
    radial-gradient(25% 18% at 39% 42%, rgba(var(--fog-front), 0.24) 0%, transparent 70%);
  --puffs-b:
    radial-gradient(27% 20% at 42% 61%, rgba(var(--fog-front), 0.29) 0%, transparent 70%),
    radial-gradient(24% 18% at 58% 40%, rgba(var(--fog-front), 0.23) 0%, transparent 70%);
}

/* editorial/atmospheric blend the accent into the veil (the source tinted ~28% of puffs);
   quiet stays monochrome. color-mix with transparent yields the alpha tint. */
.hero--editorial .fog--front,
.hero--atmospheric .fog--front {
  --puffs-a:
    radial-gradient(24% 18% at 48% 46%, color-mix(in srgb, var(--color-primary) 20%, transparent) 0%, transparent 70%),
    radial-gradient(28% 21% at 59% 58%, rgba(var(--fog-front), 0.30) 0%, transparent 70%),
    radial-gradient(25% 18% at 39% 42%, rgba(var(--fog-front), 0.24) 0%, transparent 70%);
  --puffs-b:
    radial-gradient(23% 17% at 52% 52%, color-mix(in srgb, var(--color-primary) 18%, transparent) 0%, transparent 70%),
    radial-gradient(27% 20% at 42% 61%, rgba(var(--fog-front), 0.29) 0%, transparent 70%),
    radial-gradient(24% 18% at 58% 40%, rgba(var(--fog-front), 0.23) 0%, transparent 70%);
}

/* Durations 31/43/53s — still mutually prime-ish, so the layers never sync into a visible
   loop. The preset shipped 90/110/130s, which moves the fog at roughly 1.5-2 px/s: below
   the threshold of perception, so the hero read as a still image. These are slow enough to
   stay calm and fast enough to be seen drifting. Transform-only, so it stays on the
   compositor and costs no layout. */
/* Radial emanation — the fog grows OUTWARD from the centre of the hero instead of sliding
   sideways. Three details make it read as a continuous flow rather than a loop:

   1. `infinite`, not `alternate`. Alternating would scale up then back down, which reads as
      breathing in and out; emanation has to always travel one way.
   2. Each layer fades to opacity 0 at BOTH ends of its cycle, so the jump from the large
      scale back to the small one happens while the layer is invisible.
   3. Negative delays stagger the three layers across their cycles, so they never fade out
      together and the hero is never momentarily bare.

   transform-origin is the default 50% 50% — the hero centre, since every layer is inset
   symmetrically. Both transform and opacity are compositor properties: no layout, no paint. */
/* Every layer emanates the same way — one direction only, never `alternate`. Each twin runs
   identical keyframes with the ::after starting half a duration earlier, so the pair's
   opacities always sum to 1 and the layer is continuously present. All three layers now use
   this, including the noise: it previously churned with `alternate`, which scaled it in and
   out and was the most visible source of the "inward then outward" cycle. */
@media (prefers-reduced-motion: no-preference) {
  .fog--back::before {
    animation: fog-emanate 22s linear infinite;
  }

  .fog--back::after {
    animation: fog-emanate 22s linear -11s infinite;
  }

  .fog--noise::before {
    animation: fog-emanate 17s linear infinite;
  }

  .fog--noise::after {
    animation: fog-emanate 17s linear -8.5s infinite;
  }

  .fog--front::before {
    animation: fog-emanate 29s linear infinite;
  }

  .fog--front::after {
    animation: fog-emanate 29s linear -14.5s infinite;
  }
}

/* Linear timing plus a midpoint scale exactly between the endpoints keeps the outward travel
   uniform; the triangular opacity is what makes two offset copies sum to a constant. The
   range is wide (0.8 -> 1.9, a 2.4x sweep) so the radiation is unmistakable — and 0.8 of a
   layer inset -20% is still 112% of the hero, so no edge can ever show. */
@keyframes fog-emanate {
  0% { transform: scale(0.8); opacity: 0; }
  50% { transform: scale(1.35); opacity: 1; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* ---------- hero — quiet (default) ---------- */

.hero-center {
  position: relative;
  text-align: center;
  max-width: 900px;
  margin: 0 auto;
}

/* Text-protection scrim. The fog layers blend with mix-blend-mode: screen, which only ever
   LIGHTENS, and they drift — so without this the contrast under a given word changes over
   time and dips below AA where puffs overlap. This soft pool of canvas colour sits above
   the back fog and the noise but below the front veil (z-index -1 inside .hero-inner's
   stacking context), pinning the type to a known background while the fog stays visible
   all around it. It is what makes the contrast numbers in DESIGN.md hold. */
.hero-center::before {
  content: '';
  position: absolute;
  inset: -22% -16%;
  z-index: -1;
  pointer-events: none;
  /* The profile holds 0.72-0.76 out to 58% of the radius, which is past the widest line of
     type, and only then falls away — a tighter falloff left the ends of the headline
     unprotected. At 0.90 it cancelled the fog outright; 0.72 keeps roughly half the fog
     visible under the type and still clears AA at the worst composited frame. */
  background: radial-gradient(
    78% 68% at 50% 48%,
    color-mix(in srgb, var(--color-surface) 76%, transparent) 0%,
    color-mix(in srgb, var(--color-surface) 72%, transparent) 58%,
    color-mix(in srgb, var(--color-surface) 40%, transparent) 80%,
    transparent 96%
  );
}

.eyebrow {
  font-family: var(--font-family-mono);
  font-size: 12px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--color-on-surface-muted);
  margin-bottom: 26px;
}

h1 {
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-display);
  font-size: clamp(48px, 7vw, 84px);
  line-height: 1.04;
  letter-spacing: -0.01em;
  color: var(--color-on-surface-strong);
  margin: 0 auto;
  max-width: 15ch;
  text-wrap: balance;
}

/* The preset's 52px rule was set under a light serif headline. Under a 600-weight sans at up
   to 66px across three lines it read as incidental, so it scales with the type instead of
   sitting at a fixed width — still a hairline, just long enough to look placed. */
.divider {
  width: clamp(96px, 13vw, 180px);
  height: 1px;
  background: var(--color-accent-border-strong);
  margin: 34px auto 26px;
}

/* The gap below the lede separates *reading* from *acting*, so it is deliberately larger than
   the rhythm above it — the form should read as the next step, not the next paragraph. Clamped
   rather than fixed so the hero still fits one viewport on a short laptop screen. */
.hero-lede {
  font-size: clamp(15px, 1.4vw, 16.5px);
  color: var(--color-on-surface);
  margin: 0 auto clamp(36px, 4.6vw, 58px);
  max-width: 46ch;
}

form {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
  max-width: 440px;
  margin: 0 auto;
  border-bottom: 1px solid var(--color-accent-border-strong);
  padding-bottom: 10px;
}

input[type='email'] {
  flex: 1 1 20ch;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--color-on-surface-strong);
  font-family: var(--font-family);
  font-size: 15px;
  padding: 6px 2px;
}

input[type='email']:user-invalid {
  border-bottom: 1px solid var(--color-danger);
}

/* The preset had a bare `outline: none` on this input. At specificity (0,1,1) that beat the
   global `:focus-visible` rule (0,1,0), so the email field was the ONLY control on the site
   with no keyboard focus ring — a WCAG 2.4.7 failure, and visibly inconsistent next to the
   name and message fields, which never had the rule. Suppress the ring only for pointer
   focus, where the borderless field would otherwise pick up a stray browser outline. */
input[type='email']:focus:not(:focus-visible) {
  outline: none;
}

button {
  background: transparent;
  border: 0;
  color: var(--color-primary);
  font-family: var(--font-family-mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 4px;
}

button:hover {
  color: var(--color-primary-hover);
}

.consent {
  letter-spacing: 0.06em;
  color: var(--color-on-surface-muted);
  margin: 14px auto 0;
  max-width: 46ch;
  width: 100%;
  border: 0;
  text-align: center;
}

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* entrance */

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

  .hero-center,
  .hero-block {
    opacity: 1;
    translate: 0 0;
    transition: opacity 0.9s ease, translate 0.9s ease;

    @starting-style {
      opacity: 0;
      translate: 0 12px;
    }
  }
}

/* ---------- below-the-fold content ---------- */

.content {
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(64px, 9vw, 120px) clamp(24px, 5vw, 72px) clamp(48px, 6vw, 88px);
}

.content .eyebrow {
  letter-spacing: 0.34em;
  color: var(--color-primary);
  text-align: left;
  margin-bottom: 20px;
}

h2 {
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-display);
  font-size: clamp(32px, 4.4vw, 48px);
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--color-on-surface-strong);
  margin: 0 0 24px;
  max-width: 20ch;
}

.lead {
  font-size: clamp(16px, 1.6vw, 18px);
  line-height: 1.7;
  max-width: 64ch;
  margin-bottom: 16px;
}

.lead + .lead {
  color: var(--color-on-surface-muted);
  margin-bottom: 0;
}

/* used on <h2> so the below-fold sections have real headings; the class overrides every
   h2 declaration it needs to (class beats element specificity) */
.section-label {
  font-family: var(--font-family-mono);
  font-size: 12px;
  font-weight: var(--font-weight-regular);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--color-on-surface-muted);
  max-width: none;
  margin: clamp(56px, 7vw, 80px) 0 36px;
}

.wte {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  border-top: 1px solid var(--color-accent-border);
}

.wte > div {
  padding: 30px;
  border-right: 1px solid var(--color-accent-border);
  min-width: 0;
}

.wte > div:first-child {
  padding-left: 0;
}

.wte > div:last-child {
  padding-right: 0;
  border-right: 0;
}

.wte .num {
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-display);
  font-size: 34px;
  color: var(--color-on-surface-strong);
  margin-bottom: 14px;
}

h3 {
  font-weight: var(--font-weight-label);
  font-size: 17px;
  color: var(--color-on-surface-strong);
  margin: 0 0 8px;
}

.wte p {
  font-size: 14.5px;
  color: var(--color-on-surface-muted);
}

dl {
  margin: 0;
}

dl > div {
  padding: 24px 0;
  border-top: 1px solid var(--color-accent-border);
}

dl > div:last-child {
  border-bottom: 1px solid var(--color-accent-border);
}

dt {
  font-weight: var(--font-weight-label);
  font-size: 18px;
  color: var(--color-on-surface-strong);
  margin-bottom: 10px;
}

dd {
  margin: 0;
  font-size: 15.5px;
  color: var(--color-on-surface);
  max-width: 70ch;
}

/* scroll reveal — CSS scroll-driven animation; progressive (content simply visible elsewhere) */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-reveal] {
      animation: reveal 1ms linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 40%;
    }
  }
}

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(24px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------- hero variant: editorial ---------- */

.hero--editorial {
  background: linear-gradient(180deg, #0d1424 0%, #0a1020 100%);
}

.hero--editorial::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 100% 96px, 168px 100%;
}

.hero--editorial .hero-top {
  align-items: flex-start;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.stack--right {
  text-align: right;
}

.stack .strong {
  color: var(--color-on-surface-strong);
  font-size: 15px;
  letter-spacing: 0.16em;
  font-weight: var(--font-weight-label);
}

.accent {
  color: var(--color-primary);
}

.kicker {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
  letter-spacing: 0.34em;
  color: var(--color-on-surface);
  margin-bottom: 22px;
}

.kicker::before {
  content: '';
  width: 46px;
  height: 2px;
  background: var(--color-primary);
}

.hero--editorial h1 {
  font-family: var(--font-family);
  font-weight: var(--font-weight-bold);
  font-size: clamp(64px, 12vw, 138px);
  line-height: 0.88;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  margin: 0;
  max-width: none;
}

.dot {
  color: var(--color-primary);
}

.hero--editorial .hero-lede {
  margin: 26px 0 0;
  max-width: 52ch;
  font-size: clamp(15px, 1.5vw, 17px);
}

.hero-bottom {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 40px;
  flex-wrap: wrap;
}

.hero--editorial form {
  justify-content: flex-start;
  gap: 10px;
  flex: 1 1 280px;
  max-width: 480px;
  margin: 0;
  border-bottom: 0;
  padding-bottom: 0;
}

.hero--editorial input[type='email'] {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-accent-border-strong);
  border-radius: var(--rounded-sm);
  padding: 13px 14px;
  font-size: 14px;
}

.hero--editorial button,
.hero--atmospheric button {
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: var(--font-family);
  font-weight: var(--font-weight-label);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: none;
  padding: 13px 22px;
  border-radius: var(--rounded-sm);
}

.hero--editorial button:hover,
.hero--atmospheric button:hover {
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

.hero--editorial .consent,
.hero--atmospheric .consent {
  text-align: left;
  margin: 14px 0 0;
}

.hero--atmospheric .consent {
  text-align: center;
  margin: 14px auto 0;
}

/* ---------- hero variant: atmospheric ---------- */

.hero--atmospheric {
  background: radial-gradient(90% 70% at 50% 62%, #131c33 0%, #0a1020 60%, #06090f 100%);
  text-align: center;
}

.glow {
  position: absolute;
  left: 50%;
  top: 56%;
  width: min(760px, 90vw);
  height: min(760px, 90vw);
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--color-primary) 0%, transparent 62%);
  opacity: 0.2;
  filter: blur(6px);
}

/* held at the verified maxima, not the preset's 0.7 / 0.5 — if this variant is ever switched
   on, exceeding them would invalidate the contrast table in DESIGN.md */
.hero--atmospheric .fog--back {
  opacity: 0.63;
}

.hero--atmospheric .fog--front {
  opacity: 0.48;
}

.hero-top--center {
  justify-content: center;
}

.wordmark-caps {
  font-weight: var(--font-weight-label);
  font-size: 15px;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--color-on-surface-strong);
}

.hero--atmospheric h1 {
  font-family: var(--font-family);
  font-weight: var(--font-weight-bold);
  font-size: clamp(72px, 13vw, 144px);
  line-height: 0.9;
  letter-spacing: -0.02em;
  max-width: none;
}

.hero--atmospheric form {
  gap: var(--spacing-sm);
  max-width: 460px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--color-accent-border-strong);
  border-bottom: 1px solid var(--color-accent-border-strong);
  border-radius: var(--rounded-pill);
  padding: 7px 7px 7px 22px;
  backdrop-filter: blur(12px);
}

.hero--atmospheric input[type='email'] {
  font-size: 15px;
}

.hero--atmospheric button {
  letter-spacing: 0;
  padding: 12px 26px;
  border-radius: var(--rounded-pill);
}

/* ---------- footer ---------- */

footer {
  border-top: 1px solid var(--color-accent-border);
  padding: clamp(36px, 5vw, 56px) clamp(24px, 5vw, 72px);
}

.footer-inner {
  max-width: 1080px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.footer-inner .wordmark {
  font-size: 18px;
}

footer nav {
  display: flex;
  gap: 26px;
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-on-surface-meta);
}

.copyright {
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--color-on-surface-meta);
}

/* ---------- reduced motion: fog freezes to a single frame, everything else stills ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Cross-document transitions are opted into only where motion is welcome, so reduced
   motion means a plain instant navigation (web-static Page Transitions rule). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }

  /* 200ms both directions. The preset shipped 1.2s ease-in on the OLD root — that is the
     launch-day "fog lifts" reveal, but it also applied to every in-site click, where a
     full-height fogged hero dissolving into a short legal page for over a second reads as
     a rendering bug (both pages visible at once). Re-add the 1.2s on launch day only, on
     the page being replaced. */
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 200ms;
    animation-timing-function: ease;
  }
}

/* ════════════════════════ JUG.ba adaptations ════════════════════════
   Everything above is designs/smoke/style.css verbatim. Below: only what the preset
   deliberately did not ship (see designs/smoke/DESIGN.md § "Not carried over") plus two
   documented deviations. Tokens only — no new literal colors. */

/* Deviation 1 — h1 measure. The preset's placeholder headline is a short poetic line set
   at 15ch/84px. home R1.1 requires the factual entity sentence, which is longer, so it
   needs a wider measure and a lower ceiling to still set in three lines. */
/* The vh cap only engages on genuinely short viewports; at 900px tall it is inert. Without it
   a three-line headline plus the form cannot fit one screen on a short laptop. */
h1 {
  max-width: 22ch;
  font-size: min(clamp(38px, 5.6vw, 72px), 9.5vh);
}

/* Deviation 2 — signup row. The preset put the hairline on the <form>, so it drew below
   every child, including the consent line. Moving it to a wrapper around just the input +
   button restores the reference's "rule directly under the field" and makes room for the
   opt-in below it. */
.hero-center form {
  display: block;
  max-width: 440px;
  margin: 0 auto;
  border-bottom: 0;
  padding-bottom: 0;
}

.signup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-sm);
  border-bottom: 1px solid var(--color-accent-border-strong);
  padding-bottom: 10px;
}

/* the contribute opt-in — the preset's hero form has no checkbox */
/* Tracking is 0.06em to match .consent rather than 0.1em: at 11px monospace that buys about
   35px, which is what lets the label sit on one line at the form's 440px width. On a narrow
   viewport it wraps to two lines, so `flex-start` + left alignment keeps the box beside the
   FIRST line instead of floating in the middle of the text block. The whole <label> is the
   hit target, which is what satisfies WCAG 2.5.8 — the 15px box alone would not. */
.optin {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: var(--spacing-sm);
  margin-top: 18px;
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--color-on-surface-muted);
  text-align: left;
  cursor: pointer;
}

.optin input[type='checkbox'] {
  accent-color: var(--color-primary);
  flex: none;
  inline-size: 15px;
  block-size: 15px;
  margin: 0;
  margin-block-start: 1px;
}

/* ---------- sticky site header ----------
   From the Claude Design handoff; designs/smoke never imported the header shells (see its
   DESIGN.md § "Not carried over"). Pure CSS, no scroll listener:

   - on the landing page the element sits AFTER the hero, so the hero keeps its own wordmark
     and the bar only appears once you scroll into the content, then stays;
   - on the plain pages it is the first child of <body>, so it is pinned from the start.

   z-index 3 clears .fog--front (2). scroll-padding-top keeps in-page anchors clear of it. */

html {
  scroll-padding-top: 72px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-lg);
  flex-wrap: wrap;
  padding: 13px clamp(24px, 5vw, 72px);
  background: color-mix(in srgb, var(--color-surface) 84%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-accent-border);
}

.site-header .wordmark {
  font-size: 17px;
  text-decoration: none;
}

.site-links {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-on-surface-meta);
}

/* 24px gap keeps these small targets from failing WCAG 2.5.8: undersized targets pass when a
   24px circle centred on each does not overlap a neighbour. The vertical padding on the bar
   gives the same clearance above and below. */
.site-links a[aria-current='page'] {
  color: var(--color-primary);
}

/* Skip link — first focusable element on every page, so a keyboard or screen-reader user can
   jump the sticky nav. Off-screen until focused rather than display:none, which would remove
   it from the tab order entirely. z-index clears the sticky bar (3). */
.skip-link {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: -9999px;
  z-index: 4;
  padding: 11px 18px;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}

.skip-link:focus {
  inset-inline-start: 0;
}

/* the skip target is focused programmatically, so it must never show a focus ring */
main:focus {
  outline: none;
}

/* ---------- link decoration, split by context ----------
   Navigation links lose the underline: they are standalone, inside a nav landmark or a
   dedicated line, so there is no surrounding prose they could be mistaken for. Position,
   cursor and the hover colour carry the affordance, which is the universal convention.

   Links INSIDE prose keep theirs, and must. `a { color: inherit }` means an inline link is
   the same colour as the sentence around it, so the underline is its ONLY distinction —
   removing it would make the "privacy note" link and the imprint/privacy mailto addresses
   invisible, and fail WCAG 1.4.1 (Use of Color). Do not "tidy" these away. */

nav a,
.back a {
  text-decoration: none;
}

.consent a,
.lead a {
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

/* ---------- shell for the plain pages (404, imprint, privacy, both thanks) ----------
   the preset ships no `main` rule at all — it assumes .hero / .content / footer only. */

main.page {
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(72px, 10vw, 132px) clamp(24px, 5vw, 72px) clamp(48px, 6vw, 88px);
}

main.page > * + * {
  margin-block-start: var(--spacing-lg);
}

main.page h1 {
  font-size: clamp(34px, 4.6vw, 52px);
  max-width: 24ch;
  margin: 0 0 var(--spacing-xl);
}

/* the legal pages carry many short sections, so the landing page's 56-80px label spacing
   would turn them into a scroll marathon */
main.page .section-label {
  margin: clamp(38px, 4.6vw, 54px) 0 14px;
}

main.page code,
main.page samp {
  font-family: var(--font-family-mono);
  font-size: 0.9em;
  color: var(--color-on-surface-strong);
}

.back {
  margin-block-start: var(--spacing-xxl);
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-on-surface-meta);
}

/* ---------- contact form ----------
   the preset styles a single inline email field in the hero; the contact BC needs a
   stacked form with name, email, and a textarea. */

form.stacked {
  display: grid;
  gap: var(--spacing-lg);
  max-width: 52ch;
  margin: 0;
  border-bottom: 0;
  padding-bottom: 0;
  /* The preset's unscoped `form` rule is written for the hero's one-line field and sets
     justify-content/align-items to center. Grid skips auto-track stretching unless these are
     normal or stretch (CSS Grid 12.8), so without this reset the column is max-content sized:
     every input took its width from the longest child rather than the 52ch measure, and
     editing the consent sentence silently resized the whole form. */
  justify-content: normal;
  align-items: normal;
}

.field {
  display: grid;
  gap: var(--spacing-sm);
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-on-surface-muted);
}

form.stacked input[type='text'],
form.stacked input[type='email'],
form.stacked textarea {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-accent-border-strong);
  border-radius: var(--rounded-sm);
  color: var(--color-on-surface-strong);
  font-family: var(--font-family);
  font-size: 15px;
  letter-spacing: normal;
  text-transform: none;
  padding: 12px 14px;
  flex: none;
  min-width: 0;
}

form.stacked textarea {
  min-height: 9rem;
  resize: vertical;
}

form.stacked input:user-invalid,
form.stacked textarea:user-invalid {
  border-color: var(--color-danger);
}

form.stacked button {
  justify-self: start;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: var(--font-family);
  font-weight: var(--font-weight-label);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: none;
  padding: 13px 22px;
  border-radius: var(--rounded-sm);
}

form.stacked button:hover {
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

form.stacked .consent {
  margin: 0;
  max-width: 52ch;
  text-align: left;
}
