/* ==========================================================================
   tero.hr
   Design spec: docs/superpowers/specs/2026-08-11-tero-hr-redesign-design.md
   Read the spec before changing values here. Several of them look arbitrary
   and are not; the ones that bite are flagged inline.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts. Inter variable, self-hosted (no third-party request, no GDPR
   exposure from Google Fonts). Two subsets: latin, plus latin-ext for the
   Croatian diacritics (č ć ž š đ).
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../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: 100 900;
  font-display: swap;
  src: url('../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;
}

/* --------------------------------------------------------------------------
   Theme tokens.

   DARK IS THE DEFAULT, for everyone. `prefers-color-scheme` is deliberately
   not consulted: the OS setting does not affect this site. The only way to get
   the light theme is the toggle, and that choice is remembered in localStorage
   and stamped onto <html data-theme="light"> before first paint.

   `color-scheme` is set alongside so scrollbars, form controls and the
   browser's own canvas match the theme rather than staying light.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: dark;
  --bg: #0d1020;
  --text: #e6e8f5;
  --muted: #a2a7c8;
  --accent-1: #6c6cff;
  --accent-2: #22d3ee;
  --accent-text-1: #a5a3ff;
  --accent-text-2: #67e8f9;
  --border: rgba(255, 255, 255, .09);
  --border-strong: rgba(255, 255, 255, .14);
  --chip: rgba(255, 255, 255, .06);
  --card-solid: rgba(255, 255, 255, .045);
  --nav-bg: rgba(19, 23, 45, .62);
  --nav-shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px rgba(0, 0, 0, .4);
  --surface-shadow: none;
  --bloom-1: rgba(108, 108, 255, .55);
  --bloom-2: rgba(34, 211, 238, .32);
  --grid-line: rgba(255, 255, 255, .055);
  --pulse-rgb: 165, 163, 255;
  --tech-mono: #8891ad;

  /* Buttons carry white text, so their gradient CANNOT use --accent-2: white on
     #22d3ee measures 1.81:1 and on #0aa6c4 2.89:1, both far below the 4.5:1
     minimum. These two are measured at 6.29:1 and 5.36:1. The bright cyan stays
     in decorative use (hero bands, headline sweep) where nothing sits on it.
     Not theme-aware on purpose — the text is white in both themes. */
  --btn-1: #4f46e5;
  --btn-2: #0e7490;
}

/* The only way to get light: the visitor clicks the toggle. prefers-color-scheme
   is deliberately NOT consulted — dark is the default for everyone, and the
   choice is remembered in localStorage. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f6fd;
  --text: #0f1424;
  --muted: #545c7d;
  --accent-1: #5b56e8;
  --accent-2: #0aa6c4;
  --accent-text-1: #4f46e5;
  --accent-text-2: #0891b2;
  --border: rgba(15, 23, 42, .07);
  --border-strong: rgba(15, 23, 42, .13);
  --chip: rgba(15, 23, 42, .05);
  --card-solid: #ffffff;
  --nav-bg: rgba(255, 255, 255, .72);
  --nav-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 8px 24px rgba(15, 23, 42, .08);
  --surface-shadow: 0 1px 2px rgba(15, 23, 42, .035), 0 0 24px 3px rgba(80, 80, 190, .07);
  --bloom-1: rgba(108, 108, 255, .30);
  --bloom-2: rgba(34, 211, 238, .26);
  --grid-line: rgba(15, 23, 42, .07);
  --pulse-rgb: 79, 70, 229;
  --tech-mono: #6b7285;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 16px;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  transition: background .4s ease, color .4s ease;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; color: inherit; cursor: pointer; }

:focus-visible { outline: 2px solid var(--accent-1); outline-offset: 3px; border-radius: 6px; }

.skip { position: absolute; left: -9999px; top: 12px; z-index: 100; padding: 12px 18px; border-radius: 10px; background: var(--bg); border: 1px solid var(--border-strong); }
.skip:focus { left: 16px; }

.wrap { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 20px; }
@media (min-width: 768px) { .wrap { padding: 0 32px; } }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   Navigation — fixed, and OUTSIDE .hero on purpose: .hero is overflow:hidden
   and would clip a fixed child. The bar spans the viewport but only the pill
   takes pointer events, so it doesn't swallow clicks across the full width.
   -------------------------------------------------------------------------- */
.navbar { position: fixed; top: 14px; left: 0; right: 0; z-index: 40; pointer-events: none; }
.navbar .wrap { pointer-events: none; }

/* mobile: spacer | logo | burger, so the logo sits optically centred */
.nav {
  pointer-events: auto;
  display: grid; grid-template-columns: 44px 1fr 44px; align-items: center;
  padding: 8px; border-radius: 999px;
  background: var(--nav-bg); border: 1px solid var(--border);
  box-shadow: var(--nav-shadow);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.nav-spacer { display: block; }
.nav .logo { justify-self: center; }
.nav-right { justify-self: end; display: flex; align-items: center; gap: 7px; }

@media (min-width: 768px) {
  .nav { display: flex; justify-content: space-between; gap: 16px; padding: 8px 8px 8px 18px; }
  .nav-spacer { display: none; }
}

.logo { display: flex; align-items: center; gap: 11px; }
.logo .ic { width: 25px; fill: var(--accent-text-1); transition: fill .3s ease; }
.logo .wm { width: 68px; fill: var(--accent-text-1); transition: fill .3s ease; }
@media (min-width: 768px) { .logo .ic { width: 29px; } .logo .wm { width: 79px; } }

/* .intro is added on load and stripped once it finishes, so the load spin and
   the hover spin never fight over the same animation property */
.logo .ic.intro { animation: spin 1s cubic-bezier(.68, -.5, .27, 1.5) both .1s; }
@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

@media (hover: hover) {
  .logo:hover .ic:not(.intro) { animation: spin 1s cubic-bezier(.68, -.55, .265, 1.55); }
  /* both marks shift to heading colour on hover, same --text the h2s inherit */
  .logo:hover .ic, .logo:hover .wm { fill: var(--text); }
}

/* hidden on mobile (the panel carries the links), shown from 768px up */
.nav-links { display: none; gap: 2px; font-size: .875rem; font-weight: 450; color: var(--muted); }
@media (min-width: 768px) { .nav-links { display: flex; } }
.nav-links a { position: relative; padding: 9px 13px; color: var(--muted); transition: color .25s ease; }
/* underline only, opening outward from the centre */
.nav-links a::after {
  content: ""; position: absolute; left: 50%; right: 50%; bottom: 2px; height: 1.5px; border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-2));
  transition: left .28s cubic-bezier(.2, .8, .3, 1), right .28s cubic-bezier(.2, .8, .3, 1);
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after { left: 13px; right: 13px; }
/* and it stays put on whichever section is in view */
.nav-links a[aria-current="true"] { color: var(--text); }
.nav-links a[aria-current="true"]::after { left: 13px; right: 13px; }

.icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 999px;
  background: var(--chip); border: 1px solid var(--border); font-size: 14px;
  transition: background .25s ease, border-color .25s ease, box-shadow .25s ease, transform .25s cubic-bezier(.2, .8, .3, 1);
}
.theme-btn .tico { display: block; transition: transform .45s cubic-bezier(.34, 1.5, .5, 1); }
@media (hover: hover) {
  .icon-btn:hover {
    background: var(--border-strong);
    border-color: color-mix(in srgb, var(--accent-1) 45%, transparent);
    box-shadow: 0 4px 16px color-mix(in srgb, var(--accent-1) 22%, transparent);
    transform: translateY(-1px);
  }
  .theme-btn:hover .tico { transform: rotate(-32deg) scale(1.14); }
}
.icon-btn:active { transform: scale(.93); }
.nav .theme-btn { display: none; }
@media (min-width: 768px) { .nav .theme-btn { display: flex; } }

/* Language: two links, not buttons. One pill slides between them; the current
   language is marked aria-current="page" and the other is an anchor. */
.lang { display: none; position: relative; padding: 3px; border-radius: 999px; background: var(--chip); border: 1px solid var(--border); transition: border-color .25s ease; }
.lang::before {
  content: ""; position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc(50% - 3px);
  border-radius: 999px; background: var(--border-strong);
  transition: transform .32s cubic-bezier(.2, .8, .3, 1), background .25s ease;
}
.lang[data-active="hr"]::before { transform: translateX(100%); }
.lang a {
  position: relative; z-index: 1; display: flex; align-items: center; justify-content: center;
  flex: 1 1 0; min-width: 38px; height: 34px;
  font-size: .75rem; font-weight: 500; border-radius: 999px; color: var(--muted);
  transition: color .25s ease;
}
.lang a[aria-current="page"] { color: var(--text); }
@media (min-width: 768px) { .lang { display: flex; } }
@media (hover: hover) {
  .lang:hover { border-color: color-mix(in srgb, var(--accent-1) 35%, transparent); }
  .lang:hover::before { background: color-mix(in srgb, var(--accent-1) 26%, var(--border-strong)); }
  .lang a:hover { color: var(--text); }
}

.cta-pill {
  display: none; align-items: center; height: 40px; padding: 0 17px; border-radius: 999px;
  font-size: .8125rem; font-weight: 500; color: #fff;
  background: linear-gradient(100deg, var(--btn-1), var(--btn-2));
  transition: transform .2s, box-shadow .2s;
}
.cta-pill:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(76, 74, 200, .3); }
@media (min-width: 768px) { .cta-pill { display: inline-flex; } }

.burger {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4.5px;
  width: 44px; height: 44px; border-radius: 999px; background: var(--chip); border: 1px solid var(--border);
}
.burger i { display: block; width: 16px; height: 1.6px; background: currentColor; border-radius: 2px; transition: transform .3s cubic-bezier(.2, .8, .3, 1), opacity .2s; }
.burger[aria-expanded="true"] i:nth-child(1) { transform: translateY(6.1px) rotate(45deg); }
.burger[aria-expanded="true"] i:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] i:nth-child(3) { transform: translateY(-6.1px) rotate(-45deg); }
@media (min-width: 768px) { .burger { display: none; } }

/* White text over a gradient whose cyan end is light; the shadow keeps it
   readable across the whole sweep, not just the indigo half. */
.cta-pill, .btn-1, .sheet-cta { text-shadow: 0 1px 2px rgba(8, 15, 40, .34); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
/* 60vh, and 60svh where supported. svh is the *small* viewport height, so the
   hero doesn't resize when mobile browser chrome hides on scroll. */
.hero { position: relative; overflow: hidden; min-height: 60vh; padding-bottom: 64px; display: flex; align-items: center; }
@supports (height: 1svh) { .hero { min-height: 60svh; } }
.hero > .wrap { width: 100%; position: relative; z-index: 2; }
@media (min-width: 768px) { .hero { padding-bottom: 96px; } }

/* "Bands": two wide diagonal sheets. No closed shape anywhere — radial blooms
   were built and rejected because discrete ellipses read as objects.
   HEIGHT MUST STAY A PERCENTAGE. The layer sits inside a viewport-sized hero;
   a px height cannot hold its proportion and previously needed breakpoints to
   patch. `top` is already a percentage, so the two share one coordinate system. */
.hero-light {
  position: absolute; left: -12%; right: -12%;
  top: -35%; height: 100%;
  z-index: 0; pointer-events: none;
  opacity: 0;
  filter: blur(44px);
  background:
    linear-gradient(102deg, transparent 10%, var(--bloom-1) 28%, transparent 46%),
    linear-gradient(102deg, transparent 52%, var(--bloom-2) 70%, transparent 88%);
  transition: opacity 1.8s ease-out;
}
.hero-light.lit { opacity: 1; }

#fx {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 24%, #000 10%, transparent 78%);
  mask-image: radial-gradient(ellipse 80% 70% at 50% 24%, #000 10%, transparent 78%);
}

/* hero content, centred at every width; padding clears the fixed nav */
.hero-body { padding-top: 132px; padding-bottom: 8px; text-align: center; }
@media (min-width: 768px) { .hero-body { padding-top: 190px; } }

/* plain arrow, not an I-beam. `cursor` inherits, so the words take it too. */
h1 {
  margin: 0 auto; max-width: 15ch;
  font-size: clamp(2.25rem, 5.2vw, 3.75rem); line-height: 1.12; letter-spacing: -.03em; font-weight: 600;
  cursor: default;
}
h1 .w { display: inline-block; opacity: 0; }

/* Accent words each carry their own slice of one ramp via --pos, so a
   transform on a word cannot kill the clipped background. The gradient is
   palindromic (indigo → cyan → white → cyan → indigo) so a repeated tile joins
   seamlessly, and the near-white band in the middle is what makes the sweep
   visible at all: panning between two similar accents barely reads.
   The padding/negative-margin pair extends the background box below the
   baseline — without it, background-clip:text shears descenders (the "g"). */
h1 .w.grad {
  --pos: 0%;
  background-image: linear-gradient(100deg,
    var(--accent-text-1) 0%,
    var(--accent-text-2) 28%,
    color-mix(in srgb, #fff 55%, var(--accent-text-2)) 50%,
    var(--accent-text-2) 72%,
    var(--accent-text-1) 100%);
  background-size: 300% 100%;
  background-position: var(--pos) 0;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  padding-bottom: .16em; margin-bottom: -.16em;
}

.lede { margin: 18px auto 0; font-size: 1rem; color: var(--muted); max-width: 58ch; text-wrap: balance; }
@media (min-width: 768px) { .lede { font-size: 1.0625rem; } }

.ctas { display: flex; flex-direction: column; justify-content: center; gap: 10px; margin-top: 30px; }
@media (min-width: 640px) { .ctas { flex-direction: row; } }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 50px; padding: 0 26px; border-radius: 999px;
  font-size: .9375rem; font-weight: 500;
  transition: transform .2s, box-shadow .2s, background .2s;
}
.btn-1 { color: #fff; background: linear-gradient(100deg, var(--btn-1), var(--btn-2)); }
.btn-1:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(76, 74, 200, .32); }
.btn-2 { border: 1px solid var(--border-strong); }
.btn-2:hover { background: var(--chip); }

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */
section { padding: 64px 0; }
@media (min-width: 768px) { section { padding: clamp(80px, 9vw, 128px) 0; } }

.label {
  font-size: .65rem; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); font-family: ui-monospace, Consolas, monospace;
}

h2 {
  margin: 14px 0 0;
  font-size: clamp(1.6rem, 3.4vw, 2.5rem); line-height: 1.15; letter-spacing: -.025em; font-weight: 600;
  max-width: 20ch; text-wrap: balance;
}

/* 72ch, not 56: these ledes are single sentences, and a paragraph-width cap
   snapped them onto a second line with a stub tail. */
.sec-lede { margin: 14px 0 0; color: var(--muted); max-width: 72ch; text-wrap: balance; }

/* --------------------------------------------------------------------------
   Services — nine cards, 3×3 at desktop. Nine divides evenly into three
   columns, so no special-casing is needed.
   -------------------------------------------------------------------------- */
.cards { display: grid; grid-template-columns: 1fr; gap: 14px; margin-top: 36px; }
@media (min-width: 640px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cards { grid-template-columns: repeat(3, 1fr); gap: 16px; } }

/* "Spotlight" background. The gradient is drawn centred in a layer twice the
   card's size so background-position alone slides it diagonally — `at x% y%`
   inside a gradient function cannot be transitioned, background-position can.
   100% 100% parks the bloom top-left; 0% 0% throws it bottom-right.
   --sx/--sy are written by JS from the pointer, so the shadow falls away from
   the cursor as though the cursor were the light source. */
.card {
  --sx: 0px; --sy: 4px;
  position: relative; overflow: hidden;
  padding: 26px 24px; border-radius: 18px;
  background-color: var(--card-solid);
  background-image: radial-gradient(62% 62% at 50% 50%, color-mix(in srgb, var(--accent-1) 24%, transparent), transparent 72%);
  background-size: 200% 200%;
  background-position: 100% 100%;
  background-repeat: no-repeat;
  border: 1px solid var(--border);
  box-shadow: var(--surface-shadow);
  cursor: default;
  transition: transform .3s cubic-bezier(.22, .85, .26, 1), border-color .3s ease,
              box-shadow .2s ease-out, background-position .55s cubic-bezier(.22, .85, .26, 1);
}

/* the icon is a watermark bleeding out of the bottom-right, not a foreground tile */
.card .ico {
  position: absolute; bottom: -18px; right: -18px;
  width: 124px; height: 124px; margin: 0;
  opacity: .12; pointer-events: none;
  transition: transform .4s cubic-bezier(.34, 1.4, .5, 1), opacity .35s ease;
}
.card .ico svg { width: 124px; height: 124px; fill: none; stroke: var(--accent-text-1); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.card h3, .card p, .card .tags { position: relative; z-index: 1; }
.card h3 { margin: 0 0 16px; font-size: 1.125rem; font-weight: 500; letter-spacing: -.01em; }
.card p { margin: 0; padding-top: 16px; border-top: 1px solid var(--border); font-size: .875rem; line-height: 1.65; color: var(--muted); }

.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 18px; padding-right: 44px; }
.tags span { padding: 5px 11px; border-radius: 999px; font-size: .725rem; font-weight: 450; color: var(--muted); background: var(--chip); }

@media (hover: hover) {
  /* two shadow layers: a symmetric halo surrounding the card, plus a softer
     directional one carrying the cursor tracking. Positive spread pushes the
     shadow out on every side instead of pooling underneath. */
  .card:hover {
    transform: translateY(-6px) scale(1.015);
    border-color: color-mix(in srgb, var(--accent-text-1) 55%, transparent);
    box-shadow:
      0 0 30px 2px rgba(76, 74, 200, .20),
      var(--sx) var(--sy) 44px 8px rgba(76, 74, 200, .26);
  }
  /* the bloom slides from top-left to bottom-right */
  .card:hover { background-position: 0% 0%; }
  .card:hover .ico { transform: rotate(-7deg) scale(1.08); opacity: .22; }
}
.card:active { transform: scale(.985); }

/* --------------------------------------------------------------------------
   Technology — one grid, everything visible at once. 24 entries divide evenly
   into 2 / 4 / 6 columns, so there is no ragged final row at any breakpoint.
   -------------------------------------------------------------------------- */
.techgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px; margin-top: 32px; }
@media (min-width: 560px) { .techgrid { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1024px) { .techgrid { grid-template-columns: repeat(6, 1fr); } }

.techcell {
  position: relative; display: flex; align-items: center; justify-content: center;
  min-height: 92px; padding: 16px 10px; border-radius: 14px; border: 1px solid transparent;
  perspective: 700px;
  transition: background .25s ease, border-color .25s ease, transform .25s cubic-bezier(.2, .8, .3, 1);
}
/* The cell flips around its Y axis on hover: front face is the monochrome
   mask, back face the real coloured file pre-rotated 180°, so the flip IS the
   colour reveal rather than a separate cross-fade. */
.techcell .flip { position: relative; width: 100%; height: 38px; transform-style: preserve-3d; transition: transform .55s cubic-bezier(.2, .8, .3, 1); }
.techcell .flip > * { position: absolute; inset: 0; margin: auto; backface-visibility: hidden; -webkit-backface-visibility: hidden; }

/* At rest every mark is painted in ONE token colour through a mask, so the row
   is genuinely uniform. grayscale() cannot do this — it preserves luminance,
   so a near-black brand (GitHub #181717) stays black while a mid-blue one
   (Docker #2496ED) goes pale, and the grid reads as 24 different greys. */
.techcell .mono {
  background: var(--tech-mono);
  -webkit-mask-image: var(--src); mask-image: var(--src);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.techcell img { height: 38px; width: auto; max-width: calc(100% - 20px); transform: rotateY(180deg); }

@media (hover: hover) {
  .techcell:hover { background: var(--chip); border-color: var(--border); transform: translateY(-3px); }
  .techcell:hover .flip { transform: rotateY(180deg); }
}
/* no hover on touch — rest on the coloured face instead */
@media (hover: none) { .techcell .flip { transform: rotateY(180deg); } }

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */
.contact-mail { display: inline-block; margin-top: 22px; font-size: clamp(1.5rem, 4.6vw, 2.75rem); font-weight: 600; letter-spacing: -.03em; }
.contact-mail.grad {
  background-image: linear-gradient(100deg, var(--accent-text-1), var(--accent-text-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  padding-bottom: .12em; margin-bottom: -.12em;
}

.faq-label { margin-top: 56px; }

/* Each question is its own panel, using the same border, radius and sliding
   spotlight bloom as the service cards, plus a "?" watermark. */
.faq { margin-top: 14px; display: grid; gap: 10px; }
.faq details {
  position: relative; overflow: hidden; perspective: 600px;
  border: 1px solid var(--border); border-radius: 16px; padding: 2px 20px;
  background-color: var(--card-solid);
  background-image: radial-gradient(62% 62% at 50% 50%, color-mix(in srgb, var(--accent-1) 16%, transparent), transparent 72%);
  background-size: 200% 200%; background-position: 100% 100%; background-repeat: no-repeat;
  transition: border-color .25s ease, background-position .5s cubic-bezier(.22, .85, .26, 1);
}
.faq details::before {
  /* sized so the glyph's ink fits a closed card, anchored to the top so it
     stays beside the question rather than drifting into the answer when open.
     The transform function list must match the hover state exactly, or the
     browser falls back to matrix interpolation and a 360° turn collapses to
     no movement at all. */
  content: "?"; position: absolute; right: 56px; top: 5px; z-index: 0;
  font: 600 58px/1 'Inter', system-ui, sans-serif;
  transform: rotateY(0deg) rotate(-8deg) scale(1); transform-origin: center;
  color: var(--accent-text-1); opacity: .09;
  pointer-events: none; user-select: none;
  transition: opacity .3s ease, transform .75s cubic-bezier(.3, .7, .2, 1);
}
/* outlined rather than solid where text-stroke is supported */
@supports (-webkit-text-stroke: 1px currentColor) {
  .faq details::before { color: transparent; -webkit-text-stroke: 1.6px var(--accent-text-1); opacity: .22; }
}

.faq summary {
  position: relative; z-index: 1; list-style: none; cursor: pointer;
  padding: 16px 44px 16px 0; font-size: 1.0625rem; font-weight: 500;
  transition: color .2s ease;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 2px; top: 50%; width: 9px; height: 9px;
  border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
  transition: transform .25s ease, border-color .2s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(225deg); }
.faq p { position: relative; z-index: 1; margin: 0 0 18px; padding-right: 44px; font-size: .9375rem; line-height: 1.72; color: var(--muted); }

@media (hover: hover) {
  .faq details:hover { border-color: color-mix(in srgb, var(--accent-text-1) 45%, transparent); background-position: 0% 0%; }
  .faq summary:hover { color: var(--accent-text-1); }
  .faq summary:hover::after { border-color: var(--accent-text-1); }
  /* a full 360° turn rather than 180°, so it lands facing forward not mirrored */
  .faq details:hover::before { opacity: .38; transform: rotateY(360deg) rotate(-3deg) scale(1.06); }
}

.contact-grid { display: grid; grid-template-columns: 1fr; gap: 28px; margin-top: 44px; padding-top: 32px; border-top: 1px solid var(--border); }
@media (min-width: 768px) { .contact-grid { grid-template-columns: repeat(3, minmax(0, 280px)); gap: 48px; } }
.contact-grid h4 { margin: 0 0 10px; font-size: .65rem; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); font-family: ui-monospace, Consolas, monospace; }
.contact-grid p { margin: 0; font-size: .875rem; line-height: 1.75; color: var(--muted); }

footer { padding: 26px 0 40px; border-top: 1px solid var(--border); }
.foot-row { display: flex; flex-direction: column; gap: 8px; font-size: .75rem; color: var(--muted); }
@media (min-width: 640px) { .foot-row { flex-direction: row; justify-content: space-between; align-items: center; } }

/* --------------------------------------------------------------------------
   Mobile panel
   -------------------------------------------------------------------------- */
.sheet {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column; padding: 22px 20px 32px;
  background: var(--bg);
  opacity: 0; visibility: hidden;
  transition: opacity .3s ease, visibility .3s;
}
.sheet[data-open="true"] { opacity: 1; visibility: visible; }
.sheet-top { display: flex; align-items: center; justify-content: space-between; }
.sheet nav { display: flex; flex-direction: column; margin: auto 0; }
.sheet nav a {
  padding: 12px 0; font-size: 1.875rem; font-weight: 500; letter-spacing: -.02em;
  opacity: 0; transform: translateY(16px);
  transition: opacity .38s cubic-bezier(.19, .9, .24, 1), transform .38s cubic-bezier(.19, .9, .24, 1), color .25s ease;
}
.sheet[data-open="true"] nav a { opacity: 1; transform: none; }
.sheet[data-open="true"] nav a:nth-child(1) { transition-delay: .07s; }
.sheet[data-open="true"] nav a:nth-child(2) { transition-delay: .13s; }
.sheet[data-open="true"] nav a:nth-child(3) { transition-delay: .19s; }
@media (hover: hover) { .sheet nav a:hover { transform: translateX(6px); color: var(--accent-text-1); } }

.sheet-cta {
  display: flex; align-items: center; justify-content: center; height: 52px; border-radius: 999px;
  font-size: .9375rem; font-weight: 500; color: #fff;
  background: linear-gradient(100deg, var(--btn-1), var(--btn-2));
  opacity: 0; transform: translateY(16px);
  transition: opacity .38s .25s, transform .38s .25s;
}
.sheet[data-open="true"] .sheet-cta { opacity: 1; transform: none; }
.sheet-mail { margin-top: 14px; text-align: center; font-size: .8125rem; color: var(--muted); opacity: 0; transition: opacity .38s .3s; }
.sheet[data-open="true"] .sheet-mail { opacity: 1; }

.sheet-ctrls {
  display: flex; align-items: center; gap: 10px;
  margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--border);
  opacity: 0; transform: translateY(12px);
  transition: opacity .38s .3s, transform .38s .3s;
}
.sheet[data-open="true"] .sheet-ctrls { opacity: 1; transform: none; }
.sheet-ctrls .theme-wide {
  display: inline-flex; align-items: center; gap: 9px; height: 46px; padding: 0 18px;
  border-radius: 999px; background: var(--chip); border: 1px solid var(--border);
  font-size: .8125rem; font-weight: 450;
  transition: background .25s ease, border-color .25s ease;
}
@media (hover: hover) { .sheet-ctrls .theme-wide:hover { background: var(--border-strong); border-color: color-mix(in srgb, var(--accent-1) 40%, transparent); } }
.sheet-ctrls .theme-wide:active { transform: scale(.97); }
.sheet-ctrls .lang { display: flex; }
.sheet-ctrls .lang a { min-width: 46px; height: 40px; font-size: .8125rem; }

body[data-locked="true"] { overflow: hidden; }
@media (min-width: 768px) { .sheet { display: none; } }

/* --------------------------------------------------------------------------
   Reveal
   -------------------------------------------------------------------------- */
[data-reveal] { opacity: 0; }
[data-reveal].in { animation: rise .8s cubic-bezier(.19, .9, .24, 1) both; animation-delay: var(--d, 0s); }
@keyframes rise {
  from { opacity: 0; transform: translateY(24px) scale(.97); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* Longhand, not the shorthand-with-var() form.
   NO filter here on purpose: the accent words are background-clip:text with a
   transparent colour, and a filter on that combination paints nothing until it
   resolves, so blurred accent words stay invisible and then pop in. */
h1.in .w {
  animation-name: word;
  animation-duration: .85s;
  animation-timing-function: cubic-bezier(.19, .9, .24, 1);
  animation-delay: var(--wd, 0s);
  animation-fill-mode: both;
}
/* accent words keep the entry animation AND pan the gradient forever after */
h1.in .w.grad {
  animation-name: word, ramp;
  animation-duration: .85s, 1.5s;
  animation-timing-function: cubic-bezier(.19, .9, .24, 1), ease-in-out;
  animation-delay: var(--wd, 0s), 1.6s;
  animation-fill-mode: both, both;
  animation-iteration-count: 1, infinite;
  animation-direction: normal, alternate;
}
@keyframes word { from { opacity: 0; transform: translateY(28px) rotate(2.5deg); } to { opacity: 1; transform: none; } }
@keyframes ramp { from { background-position: var(--pos) 0; } to { background-position: calc(var(--pos) + 40%) 0; } }

/* hovering anywhere on the headline speeds the sweep up, both words together */
@media (hover: hover) {
  h1.in:hover .w.grad { animation-duration: .85s, .4s; }
}

/* --------------------------------------------------------------------------
   Reduced motion — nothing animates, and everything that animates in is
   simply visible.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition-duration: .01ms !important;
  }
  [data-reveal], h1 .w { opacity: 1 !important; }
  .hero-light { opacity: 1; }
}
