/* ==========================================================================
   U Jabka — Soda design system: BASE
   Page shell, typography scale, layout rhythm, motion and accessibility
   primitives. Everything scoped under html.theme-soda (see tokens.css).
   ========================================================================== */

/* THE ADAPTIVE SCALING LADDER — Vesper ADR-0029.
   >=1024px: one artboard scaled proportionally (1.111111vw x 1440 = 16px), so a
   rem layout keeps its proportions at every desktop width. <1024px: the ladder
   stops, rem means real pixels, each section is an authored stack — body copy
   at 1.111vw would be 4px on a 360px phone.
   Two deviations: Vesper ships two boards with a 25% jump at their seam, which
   is invisible only because its sections are sized in vw and ours in rem, so we
   keep ONE board; and scale-up is capped at the 1920 equivalent.

   THE 16px FLOOR IS THE THIRD DEVIATION, and it closes a measured readability
   hole rather than a theoretical one.

   `min(1.111111vw, 21.333px)` scales the artboard DOWN as well as up: at 1024
   the root was 11.38px, so every rem-sized label shrank with it. Measured at
   1024 across the storefront: the eyebrow rendered at 8.0px, the availability
   badge at 7.3px, the footer headings at 8.5px and the catalogue card's
   category label at 7.5px. Eight-pixel Czech uppercase with 0.3em tracking is
   not small, it is unreadable, and the brief's responsive rule is explicit that
   body and UI text may never fall below a readable floor.

   clamp() holds the root at 16px from 1024 up to 1440 and keeps the scale-up
   above it. That is the SAME trade tokens.css already records for --text-body
   and --text-small ("the vw term still does the artboard scaling, the px term
   stops it going below readable"), applied one level up so all 55 rem-sized
   labels in the system are fixed at once instead of one at a time. The
   compositional geometry is untouched: --text-display, --gutter and --container
   are vw and still scale. What stops shrinking is only the small type and the
   spacing measured in rem — which below 1024 already behaves exactly this way.

   The sub-1024 rule below is now numerically redundant and kept as the explicit
   statement of the authored-stack regime. */
html.theme-soda {
    font-size: clamp(16px, 1.111111vw, 21.333px);
}

@media (max-width: 1023.98px) {
    html.theme-soda {
        font-size: 16px;
    }
}

html.theme-soda,
html.theme-soda body {
    background: var(--page-bg);
}

html.theme-soda body {
    margin: 0;
    min-height: 100vh;
    font-family: var(--font-main);
    font-weight: 400;
    color: var(--ink);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;

    /* THE PAGE IS BLACK; THE MOOD LIVES IN THE HERO. The mood radial once sat
       here with background-attachment:fixed, which repainted the whole site in
       the brightest mood colour. It belongs to .soda-hero alone. All that is
       left here is a short fade from the hero's darkest colour into --page-bg,
       so the seam under the hero is invisible. Mood reaches the rest of the site
       through accents only — never as a full-bleed surface.
       --page-top-wash is --bg-outer on the dark ground and --page-bg on the
       light one; a theme/mood diagnostic pins both. See tokens.css. */
    background-color: var(--page-bg);
    background-image: linear-gradient(180deg,
        var(--page-top-wash) 0%,
        var(--page-bg) 26%,
        var(--page-bg) 100%);
    background-repeat: no-repeat;
    transition: background-color var(--dur-slow) var(--ease);
}

/* Legacy utility compatibility: redesigned pages do not load frontend.css, so
   the few generic sizing helpers their markup still uses are restated here. */
html.theme-soda .svg-sprite {
    position: absolute;
}

html.theme-soda .ico {
    width: 20px;
    height: 20px;
    flex: none;
    fill: none;
}

html.theme-soda .device {
    width: 116px;
    height: auto;
}

html.theme-soda .device--placeholder {
    color: var(--ink-3);
}

html.theme-soda *,
html.theme-soda *::before,
html.theme-soda *::after {
    box-sizing: border-box;
}

/* --------------------------------------------------------------- typography */

/* DISPLAY TYPE IS LIGHT, NOT BOLD — weight 300, 0.90, -0.022em. The negative
   tracking is what a large neutral sans needs at display sizes; Vesper's own
   notes record the tracking flipping negative when it left its techno face. */
html.theme-soda h1,
html.theme-soda h2,
html.theme-soda h3,
html.theme-soda h4,
html.theme-soda h5,
html.theme-soda h6 {
    font-family: var(--font-display);
    font-weight: 300;
    line-height: var(--leading-title);
    letter-spacing: var(--tracking-title);
    margin: 0;
    /* Required, not cosmetic. The legacy stylesheet is still loaded on every
       page during migration and sets `h1, h2, h3 { color: var(--ink-legacy) }`
       — a dark ink meant for a light page. Inheriting from body is not enough
       against an explicit declaration, so without this every heading rendered
       near-black on the near-black Soda background (measured 1.30:1). */
    color: var(--ink);
}

/* Section headline — THE one display size. Vesper never changes it: hero h1,
   both mid-section h2s, the Financial card and the FAQ card are all 5.556vw /
   weight 300 / 0.90, so the old clamp is gone rather than retuned.

   The two-tone <em> device is retired — Vesper's display is one uniform weight.
   The markup keeps its <em>, so it is neutralised here; `font-style: normal`
   stays load-bearing or the <em> renders italic. */
html.theme-soda .soda-sec-title {
    font-family: var(--font-display);
    font-size: var(--text-display);
    font-weight: 300;
    line-height: var(--leading-title);
    letter-spacing: var(--tracking-title);
    margin-top: .85rem;
    /* PROTECT DESCENDERS. A 0.90 line-height is tighter than the font natural
       line box, so the last line of a heading carrying ž / j / y gets cropped by
       the element box. Vesper adds exactly this pair everywhere it clips:
       padding for the glyphs, negative margin so the layout is unchanged. */
    padding-bottom: .14em;
    margin-bottom: -.14em;
}

html.theme-soda .soda-sec-title em {
    font-style: normal;
    font-weight: inherit;
    color: inherit;
}

html.theme-soda .soda-eyebrow {
    display: flex;
    align-items: center;
    gap: .7rem;
    font-family: var(--font-display);
    font-size: .7rem;
    font-weight: 500;
    letter-spacing: .3em;
    text-transform: uppercase;
    color: var(--ink-2);
    margin: 0;
}

/* The 22px accent rule that precedes an eyebrow. */
html.theme-soda .soda-eyebrow::before {
    content: '';
    width: 22px;
    height: 1px;
    background: var(--accent);
    opacity: .8;
    flex: none;
}

html.theme-soda .soda-lead {
    font-size: 1.02rem;
    line-height: 1.65;
    max-width: 40ch;
    margin-top: 1.2rem;
    color: var(--ink-2);
}

html.theme-soda p {
    margin: 0 0 1rem;
}

html.theme-soda a {
    color: inherit;
    text-decoration: none;
}

html.theme-soda .soda-prose a {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: .18em;
}

html.theme-soda .soda-prose {
    color: var(--ink-2);
    line-height: 1.7;
}

html.theme-soda .soda-prose h2,
html.theme-soda .soda-prose h3 {
    color: var(--ink);
    margin: 2.2rem 0 .8rem;
}

html.theme-soda .soda-prose h2 { font-size: 1.5rem; }
html.theme-soda .soda-prose h3 { font-size: 1.1rem; }

html.theme-soda .soda-prose li { margin-bottom: .5rem; }

/* Prices are display-face and tabular so columns line up. */
html.theme-soda .soda-price {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.16rem;
    letter-spacing: -.02em;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* .soda-price-old — a struck-through "was" price — is deliberately GONE, and
   not only because nothing rendered it. The direction forbids discount
   percentages without real source values, and this shop has no list price to
   strike through: the price shown is the price. Leaving the component in the
   sheet is an invitation to invent one. */

/* ------------------------------------------------------------------ layout */

/* The content plane: viewport minus one gutter each side. `vw` includes the
   classic scrollbar, so where one is reserved 96.667vw can exceed the client
   width; max-width clamps it back. Without a scrollbar both agree at 1392px. */
html.theme-soda .soda-container {
    width: var(--container);
    max-width: calc(100% - var(--gutter) * 2);
    margin-inline: auto;
}

html.theme-soda .soda-section {
    padding-block: var(--section-gap);
    position: relative;
    z-index: 6;
}

html.theme-soda .soda-section-head {
    margin-bottom: clamp(2rem, 4vw, 3.2rem);
}

html.theme-soda .soda-section-head--center {
    text-align: center;
}

html.theme-soda .soda-section-head--center .soda-eyebrow {
    justify-content: center;
}

html.theme-soda .soda-section-head--center .soda-lead {
    margin-inline: auto;
}

/* --------------------------------------------------------------- a11y core */

/* Visible focus everywhere. The approved reference ships zero focus styles;
   shipping that as-is would make the site keyboard-unusable. */
html.theme-soda :focus-visible {
    outline: var(--focus-ring) solid var(--focus);
    outline-offset: var(--focus-offset);
    /* No border-radius here on purpose. The ring must follow whatever shape the
       focused control already has — a 10px card, a 7px button or a square
       marker — and an outline does that by itself. Forcing one value made every
       focused element change shape while it was focused. */
}

/* Only suppress the default ring where :focus-visible is supported, so that
   removing it can never leave a control with no focus indicator at all. */
@supports selector(:focus-visible) {
    html.theme-soda :focus:not(:focus-visible) {
        outline: none;
    }
}

html.theme-soda .skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    padding: .85rem 1.4rem;
    background: var(--accent);
    color: var(--accent-ink);
    font-family: var(--font-display);
    font-weight: 600;
    border-radius: var(--r-control);
}

html.theme-soda .skip-link:focus {
    left: 0;
}

/* Screen-reader-only text that stays reachable by assistive tech. */
html.theme-soda .soda-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;
}

/* ------------------------------------------------------------------ motion */

/* Scroll reveal. Delay is set by JS via the --d custom property (CSSOM writes
   are CSP-safe; inline style attributes are not). Content is fully visible
   without JS — the reveal only ever *adds* motion to something already there. */
html.theme-soda [data-reveal] {
    opacity: 0;
    /* Vesper's UNIT_REVEAL: y 20 -> 0, blur 10px -> 0, opacity, over 1000ms
       easeOutQuint. The blur is the part that makes it read as resolving into
       focus rather than sliding in. (docs/vesper/src/views/home/reveal.ts) */
    transform: translateY(20px);
    filter: blur(10px);
    transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease), filter var(--dur-slow) var(--ease);
    transition-delay: var(--d, 0ms);
}

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

/* If JS never runs, nothing may stay invisible. */
html.theme-soda:not(.js-soda) [data-reveal] {
    opacity: 1;
    transform: none;
    filter: none;
}

@media (prefers-reduced-motion: reduce) {
    html.theme-soda *,
    html.theme-soda *::before,
    html.theme-soda *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

    html.theme-soda [data-reveal] {
        opacity: 1;
        transform: none;
        filter: none;
    }
}

/* ------------------------------------------------------------------ images */

html.theme-soda img {
    max-width: 100%;
    height: auto;
}

/* Decorative canvases. Always aria-hidden in markup; belt and braces here. */
html.theme-soda canvas {
    display: block;
}
