/* ============================================================================
   O-DOMO marketing site — design system + palette cloned from NAM.Site's
   "Obsidian" theme (pure-black void, electric violet → cyan). Kept close to the
   model site by choice. No web fonts, no CDN — system font stacks only.
   The --c-blue* names are kept for structural parity but hold the violet brand
   colour (so the app could later be recoloured to match, not the reverse).
   ============================================================================ */

:root {
    --c-bg: #000000;
    --c-bg-raise: #0b0b11;
    --c-surface: rgba(255, 255, 255, 0.04);
    --c-surface-2: rgba(255, 255, 255, 0.07);
    --c-border: rgba(255, 255, 255, 0.10);
    --c-border-strong: rgba(255, 255, 255, 0.18);
    --c-text: #f4f4f8;
    --c-text-dim: rgba(244, 244, 248, 0.58);
    --c-text-faint: rgba(244, 244, 248, 0.34);

    --c-blue: #8b3dff;
    --c-blue-deep: #5b18d6;
    --c-cyan: #00e5ff;
    --c-cyan-soft: #6ef3ff;
    --c-glow-blue: rgba(139, 61, 255, 0.35);
    --c-glow-cyan: rgba(0, 229, 255, 0.22);
    --c-ok: #45d68f;
    /* Apple Pay / Google Pay button: the brands' own light button on a dark page. */
    --c-wallet-bg: #ffffff;
    --c-wallet-fg: #000000;
    --c-bizum-bg: #05c3dd;
    --c-bizum-fg: #ffffff;

    --grad-brand: linear-gradient(100deg, var(--c-blue), var(--c-cyan), var(--c-blue));
    --grad-btn: linear-gradient(135deg, var(--c-blue-deep), var(--c-blue), var(--c-cyan));
    --shadow-btn: 0 6px 22px color-mix(in srgb, var(--c-blue) 40%, transparent);
    --shadow-card: 0 18px 48px rgba(0, 0, 0, 0.55);
}

/* ============================================================
   SWAPPABLE THEMES — every colour is a variable, so a theme is
   just an override block. Selected via <html data-site-theme="..">
   (SiteTheme service, ?theme= switch). :root = Obsidian tokens (the fallback
   layer); the default THEME is Carbon Black (SiteTheme.DEFAULT_THEME).
   ============================================================ */

html[data-site-theme="midnight"] {
    --c-bg: #070b14; --c-bg-raise: #0b1020;
    --c-surface: rgba(151, 168, 205, 0.06); --c-surface-2: rgba(151, 168, 205, 0.12);
    --c-text: #edf1f9; --c-text-dim: rgba(237, 241, 249, 0.60); --c-text-faint: rgba(237, 241, 249, 0.34);
    --c-blue: #5b9dff; --c-blue-deep: #2e6be6; --c-cyan: #40c9ff; --c-cyan-soft: #8fe3ff;
    --c-glow-blue: rgba(91, 157, 255, 0.35); --c-glow-cyan: rgba(64, 201, 255, 0.22);
}

html[data-site-theme="aurora"] {
    --c-bg: #05080a; --c-bg-raise: #0a1014;
    --c-surface: rgba(160, 230, 210, 0.06); --c-surface-2: rgba(160, 230, 210, 0.12);
    --c-text: #eefaf4; --c-text-dim: rgba(238, 250, 244, 0.60); --c-text-faint: rgba(238, 250, 244, 0.34);
    --c-blue: #2dd4bf; --c-blue-deep: #0f9d8f; --c-cyan: #4ade80; --c-cyan-soft: #a7f3d0;
    --c-glow-blue: rgba(45, 212, 191, 0.32); --c-glow-cyan: rgba(74, 222, 128, 0.22);
}

html[data-site-theme="sunset"] {
    --c-bg: #0c0710; --c-bg-raise: #140b18;
    --c-surface: rgba(255, 200, 180, 0.06); --c-surface-2: rgba(255, 200, 180, 0.12);
    --c-text: #fbf1f4; --c-text-dim: rgba(251, 241, 244, 0.60); --c-text-faint: rgba(251, 241, 244, 0.34);
    --c-blue: #ffb454; --c-blue-deep: #e0791f; --c-cyan: #ff5c8a; --c-cyan-soft: #ffa8c3;
    --c-glow-blue: rgba(255, 180, 84, 0.30); --c-glow-cyan: rgba(255, 92, 138, 0.24);
}

html[data-site-theme="ember"] {
    --c-bg: #000000; --c-bg-raise: #120a04;
    --c-surface: rgba(255, 170, 90, 0.06); --c-surface-2: rgba(255, 170, 90, 0.12);
    --c-text: #faf5ef; --c-text-dim: rgba(250, 245, 239, 0.60); --c-text-faint: rgba(250, 245, 239, 0.34);
    --c-blue: #ff8c1a; --c-blue-deep: #d96a00; --c-cyan: #ffc857; --c-cyan-soft: #ffdf9e;
    --c-glow-blue: rgba(255, 140, 26, 0.32); --c-glow-cyan: rgba(255, 200, 87, 0.20);
}

/* Theme-independent tokens (fonts, spacing) shared by every theme. */
:root {
    --font-body: "SF Pro Text", "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
    --font-display: "SF Pro Display", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
    --font-mono: ui-monospace, "Cascadia Code", "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;
    --radius: 16px;
    --radius-lg: 28px;
    --header-h: 72px;
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --maxw: 1180px;
}

* { box-sizing: border-box; }
/* Page changes are full loads (site.js): let the browser cross-fade the old page
   into the new one instead of blanking in between (same-origin, Chromium 126+;
   other browsers simply ignore it). */
@view-transition { navigation: auto; }
/* Horizontal overflow must be clipped on BOTH html and body: on mobile the
   html element can still pan sideways when only body hides it, and the slide
   entrances translate sections up to 80px past the viewport edge. `clip`
   (with `hidden` fallback) blocks it without creating a scroll container. */
html, body { margin: 0; padding: 0; max-width: 100%; overflow-x: hidden; overflow-x: clip; }

body {
    font-family: var(--font-body);
    font-size: 17px;
    line-height: 1.6;
    color: var(--c-text);
    /* The page colour is on <html> (App.razor inlines it for the first paint, the
       rule below keeps it in step with the theme). body stays transparent: with a
       background on <html>, a body background is no longer moved to the canvas and
       would cover the fixed background layers (grid, aurora, carbon weave, sheen). */
    background: transparent;
    -webkit-font-smoothing: antialiased;
    /* NO overflow-x here: "hidden" on body (html has its own) made body a scroll
       container that never scrolls, which silently broke the sticky header (it
       scrolled away with the page). The html, body rule above clips instead. */
}
html { background: var(--c-bg); }
/* The header is sticky: a #anchor jump (menu "How it works" -> /#how) must land
   below it, not with the section title hidden under the bar. */
[id] { scroll-margin-top: calc(var(--header-h) + 12px); }

::selection { background: var(--c-glow-blue); color: #fff; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { font-family: var(--font-display); line-height: 1.1; letter-spacing: -0.02em; margin: 0; }
img { max-width: 100%; display: block; }

/* ---------- ambient background ---------- */
.site-shell { position: relative; min-height: 100vh; display: flex; flex-direction: column; }

.bg-grid {
    position: fixed; inset: 0; z-index: -3; pointer-events: none;
    background-image:
        linear-gradient(rgba(91, 157, 255, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(91, 157, 255, 0.05) 1px, transparent 1px);
    background-size: 72px 72px;
    transform: perspective(600px) rotateX(56deg) scale(1.6) translateY(-10%);
    transform-origin: top center;
    -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 20%, transparent 70%);
    mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 20%, transparent 70%);
    animation: grid-breathe 9s var(--ease-out) infinite;
}
@keyframes grid-breathe { 0%, 100% { opacity: .5; } 50% { opacity: .85; } }

.bg-aurora {
    position: fixed; inset: -20%; z-index: -2; pointer-events: none;
    background:
        radial-gradient(45% 45% at 18% 12%, var(--c-glow-blue), transparent 60%),
        radial-gradient(40% 40% at 82% 20%, var(--c-glow-cyan), transparent 60%),
        radial-gradient(50% 50% at 70% 88%, rgba(46, 107, 230, 0.18), transparent 62%);
    filter: blur(48px);
    animation: aurora-drift 26s ease-in-out infinite alternate;
}
@keyframes aurora-drift { 0% { transform: translate3d(0,0,0); } 100% { transform: translate3d(-4%, 3%, 0); } }

/* Star canvas — a background layer, must be out of flow like grid/aurora,
   otherwise it takes a full viewport of space and pushes the header down. */
#odo-stars {
    position: fixed; inset: 0; width: 100%; height: 100%;
    z-index: -1; pointer-events: none;
}

/* ---------- header ---------- */
.site-header {
    position: sticky; top: 0; z-index: 40; height: var(--header-h);
    display: flex; align-items: center; gap: 20px;
    padding: 0 clamp(16px, 4vw, 40px);
    background: color-mix(in srgb, var(--c-bg) 62%, transparent);
    backdrop-filter: saturate(160%) blur(16px);
    -webkit-backdrop-filter: saturate(160%) blur(16px);
    border-bottom: 1px solid var(--c-border);
}
.brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700; }
.brand-logo { height: 52px; width: auto; }
.header-nav { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.header-link { color: var(--c-text-dim); font-weight: 600; font-size: .95rem; transition: color .15s; }
.header-link:hover { color: var(--c-text); }
.header-actions { display: flex; align-items: center; gap: 10px; }
.nav-toggle { display: none; }
.nav-burger { display: none; }

/* ---------- buttons ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-family: var(--font-display); font-weight: 600; font-size: 1rem;
    border-radius: 999px; padding: 12px 24px; cursor: pointer; border: 1px solid transparent;
    transition: transform .2s var(--ease-out), box-shadow .2s, background .2s, border-color .2s;
    white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn-primary { background: var(--c-blue); color: #fff; box-shadow: var(--shadow-btn); }
.btn-primary:hover { background: var(--c-blue-deep); }
.btn-ghost { background: var(--c-surface); color: var(--c-text); border-color: var(--c-border-strong); }
.btn-ghost:hover { background: var(--c-surface-2); }
.btn-sm { padding: 8px 16px; font-size: .9rem; }
.btn-lg { padding: 15px 32px; font-size: 1.08rem; }
.btn-block { width: 100%; }
/* Stacked full-width buttons never touch (2026-10-27: "Se connecter" sat glued to
   "Choisir une autre offre" on /subscribe; same pattern on account, cart, checkout).
   .cta-yr is excluded: it is the monthly/annual TWIN of the .cta-mo before it and
   only one of the two is ever shown. Flex lists with their own gap reset it. */
.btn-block + .btn:not(.cta-yr), .btn + .btn-block:not(.cta-yr) { margin-top: 10px; }
:is(.acct-links, .acct-confirm, .pay-choice, .hero-actions, .header-actions, .pa-actions) > .btn + .btn { margin-top: 0; }

/* ---------- sections ---------- */
.site-main { flex: 1; }
.section { max-width: var(--maxw); margin: 0 auto; padding: clamp(56px, 9vw, 120px) clamp(16px, 4vw, 40px); }
.section-title { font-size: clamp(2rem, 4.5vw, 3.2rem); font-weight: 800; margin-bottom: 14px; }
.section-sub { color: var(--c-text-dim); font-size: 1.15rem; max-width: 640px; }
.gradient-text {
    background: var(--grad-brand); background-size: 200% auto;
    -webkit-background-clip: text; background-clip: text; color: transparent;
    animation: gradient-slide 6s linear infinite; padding-bottom: .08em;
}
@keyframes gradient-slide { to { background-position: 200% center; } }

/* ---------- hero ---------- */
.hero {
    display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(24px, 5vw, 64px);
    align-items: center; min-height: 88vh;
    max-width: var(--maxw); margin: 0 auto; padding: clamp(40px, 7vw, 80px) clamp(16px, 4vw, 40px);
}
/* hero copy is not selectable (user-select inherits to all children) */
.hero { -webkit-user-select: none; -moz-user-select: none; user-select: none; }
/* headings get programmatic focus via FocusOnNavigate — hide that focus ring */
h1:focus, h1:focus-visible { outline: none; }
.hero-eyebrow { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .22em; font-size: .8rem; color: var(--c-cyan); margin-bottom: 18px; }
.hero-title { font-size: clamp(2.4rem, 5.5vw, 4.8rem); font-weight: 800; }
.hero-sub { color: var(--c-text-dim); font-size: clamp(1.05rem, 2vw, 1.3rem); margin: 22px 0 32px; max-width: 540px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-note { margin-top: 18px; color: var(--c-text-faint); font-size: .9rem; }
.hero-visual { position: relative; }
.hero-img-wrap { position: relative; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--c-border); box-shadow: var(--shadow-card); aspect-ratio: 3 / 2; }
.hero-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-img-glow { position: absolute; inset: -30% -10% -30% -10%; z-index: -1; background: radial-gradient(50% 50% at 50% 50%, var(--c-glow-blue), transparent 70%); filter: blur(40px); }

/* ---------- feature grids (how / benefits) ---------- */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 40px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 40px; }

.card {
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius);
    padding: 24px; transition: transform .3s var(--ease-out), border-color .3s, background .3s;
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.card:hover { transform: translateY(-4px); border-color: var(--c-border-strong); background: var(--c-surface-2); }
.card-img-wrap { border-radius: 12px; overflow: hidden; margin: -4px -4px 16px; aspect-ratio: 16 / 11; }
.card-img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s var(--ease-out); }
.card:hover .card-img { transform: scale(1.05); }
.card-num { font-family: var(--font-mono); color: var(--c-cyan); font-size: .85rem; letter-spacing: .1em; }
.card-title { font-size: 1.25rem; font-weight: 700; margin: 8px 0; }
.card-body { color: var(--c-text-dim); font-size: .98rem; }

.benefit-card .card-img-wrap { aspect-ratio: 1 / 1; }

/* ---------- pricing ---------- */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; margin-top: 44px; align-items: stretch; }
.price-card {
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg);
    padding: 30px 26px; display: flex; flex-direction: column; gap: 6px;
    transition: transform .3s var(--ease-out), box-shadow .3s, border-color .3s;
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.price-card:hover { transform: translateY(-5px); box-shadow: 0 0 0 1px var(--c-glow-blue), var(--shadow-card); }
.price-card.featured { border-color: color-mix(in srgb, var(--c-blue) 55%, transparent); box-shadow: 0 0 0 1px var(--c-glow-blue); }
.price-badge { align-self: flex-start; font-family: var(--font-mono); font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--c-cyan); background: var(--c-surface-2); border-radius: 999px; padding: 4px 12px; margin-bottom: 8px; }
.price-name { font-size: 1.25rem; font-weight: 700; }
.price-amount { font-family: var(--font-display); font-size: clamp(2.2rem, 4vw, 3rem); font-weight: 800; line-height: 1.1; }
.price-per { color: var(--c-text-dim); font-size: .95rem; }
.price-desc { color: var(--c-text-dim); font-size: .95rem; margin: 8px 0 14px; }
.price-list { list-style: none; margin: 0 0 20px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.price-list li { display: flex; gap: 8px; align-items: flex-start; color: var(--c-text); font-size: .95rem; }
.price-list li::before { content: "✓"; color: var(--c-ok); font-weight: 800; }
.price-card .btn { margin-top: auto; }
.pricing-foot { text-align: center; margin-top: 24px; color: var(--c-text-faint); font-size: .9rem; }

/* The add-on row: minmax 180px keeps all five on one line at full width
   (content ≈1100px → 5×180 + 4×20 gap = 980px). */
.pricing-grid.addons { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); margin-top: 20px; }
/* Secondary to the two plan cards, and it keeps the longest translated names
   (CA "comandament", NL "Afstandsbedieningsmodule") inside a 180px column. */
.pricing-grid.addons .price-name { font-size: 1.12rem; }

/* ---- align the rows ACROSS the cards ----
   Card titles wrap to a different number of lines per language (CA "Mòdul
   comandament a distància" takes three, EN "Wall tablet" one), which staggered
   every price, caption and description down the row. Subgrid makes each card
   share the grid's row tracks, so name / price / caption / description / button
   line up whatever the wrapping — no per-language height to maintain.
   The card keeps its own 6px row-gap, which overrides the parent's 20px, so
   spacing inside a card is unchanged and 20px still separates wrapped bands.
   Row counts are exact and must stay in sync with UcPricing.razor:
     .plans  = name, price, per, desc, feature list, CTA          (6)
     .addons = name, price, per, desc, CTA                        (5)
   The inactive monthly/annual CTA is display:none, so it never occupies a row.
   Browsers without subgrid simply fall back to the previous ragged layout. */
@supports (grid-template-rows: subgrid) {
    /* grid-template-columns is required: without it the card's single implicit
       column is auto-sized and can grow past the card, clipping long text. */
    .pricing-grid.plans > .price-card,
    .pricing-grid.addons > .price-card { display: grid; grid-template-rows: subgrid; grid-template-columns: minmax(0, 1fr); }
    .pricing-grid.plans > .price-card { grid-row: span 6; }
    .pricing-grid.addons > .price-card { grid-row: span 5; }
}

/* "Recommended" sits outside the flow so the featured card has the same row
   count as the plain one; both reserve the space with padding instead. */
.pricing-grid.plans > .price-card { padding-top: 52px; }
.pricing-grid.plans .price-badge { position: absolute; top: 22px; left: 26px; margin-bottom: 0; }

/* Long compounds have to fit a 180px card: NL "Afstandsbedieningsmodule" is one
   unbreakable 24-character word, CA "Mòdul comandament a distància" is three
   lines. App.razor sets <html lang>, so hyphens:auto breaks them at proper
   syllables; overflow-wrap is only the last-resort fallback that stops an
   overflow when no dictionary is available. */
.price-name { -webkit-hyphens: auto; hyphens: auto; overflow-wrap: break-word; }

/* ---------- compatibility strip (UcCompatLogos) ----------
   Protocol NAMES set in our own display face, never the owners' logos or brand
   type — see the note at the top of UcCompatLogos.razor before changing this. */
.compat { padding-top: 0; text-align: center; }
.compat-eyebrow { color: var(--c-text-faint); margin-bottom: 18px; }
.compat-row { list-style: none; margin: 0; padding: 0; display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; }
.compat-row li { font-family: var(--font-display); font-size: clamp(1.55rem, 3.6vw, 2.4rem); font-weight: 700; letter-spacing: -.02em; line-height: 1.35; color: var(--c-text); }
/* Separator lives on the item so it wraps with it and never dangles on a line end. */
.compat-row li + li::before { content: "·"; color: var(--c-text-faint); font-weight: 400; margin: 0 .55em; }
.compat-note { max-width: 620px; margin: 20px auto 0; color: var(--c-text-faint); font-size: .8rem; line-height: 1.55; }

/* small left-aligned footnote under a feature section (e.g. Remote Control) */
.section-foot { margin-top: 22px; color: var(--c-text-faint); font-size: .9rem; max-width: 760px; }

/* ---------- monthly / annual billing switch (CSS-only, no JS) ---------- */
.bill-radio { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.billing-toggle {
    display: inline-flex; gap: 4px; margin: 28px auto 0; padding: 5px;
    border: 1px solid var(--c-border); border-radius: 999px; background: var(--c-surface);
    justify-self: center;
}
.section .billing-toggle { display: flex; width: max-content; margin-left: auto; margin-right: auto; }
.billing-toggle label {
    display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    padding: 9px 20px; border-radius: 999px; font-weight: 600; font-size: .95rem;
    color: var(--c-text-dim); transition: background .2s, color .2s;
}
#bill-mo:checked ~ .billing-toggle label[for="bill-mo"],
#bill-yr:checked ~ .billing-toggle label[for="bill-yr"] { background: var(--c-blue); color: #fff; }
.save-badge { font-family: var(--font-mono); font-size: .66rem; letter-spacing: .06em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px; background: color-mix(in srgb, var(--c-ok) 22%, transparent); color: #9af0c4; }
#bill-mo:checked ~ .billing-toggle label[for="bill-mo"] .save-badge,
#bill-yr:checked ~ .billing-toggle label[for="bill-yr"] .save-badge { background: rgba(255,255,255,.22); color: #fff; }

/* default = monthly shown; annual hidden until its radio is checked */
.amt-yr, .per-yr, .cta-yr { display: none; }
#bill-yr:checked ~ .pricing-grid .amt-mo,
#bill-yr:checked ~ .pricing-grid .per-mo,
#bill-yr:checked ~ .pricing-grid .cta-mo { display: none; }
#bill-yr:checked ~ .pricing-grid .amt-yr,
#bill-yr:checked ~ .pricing-grid .per-yr { display: inline; }
#bill-yr:checked ~ .pricing-grid .cta-yr { display: inline-flex; }

/* ---------- CTA band ---------- */
.cta-band { text-align: center; }
.cta-band .btn { margin-top: 24px; }

/* ---------- forms / panels ---------- */
.panel-page { max-width: 460px; margin: 0 auto; padding: clamp(48px, 8vw, 96px) 20px; }
.panel-card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg); padding: 32px; backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); box-shadow: var(--shadow-card); }
.panel-title { font-size: 1.8rem; font-weight: 800; margin-bottom: 6px; }
.panel-sub { color: var(--c-text-dim); margin-bottom: 22px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.field label { font-size: .9rem; color: var(--c-text-dim); font-weight: 600; }
.field input, .field select, .field textarea {
    background: var(--c-surface-2); border: 1px solid var(--c-border); border-radius: 12px;
    padding: 12px 14px; color: var(--c-text); font-size: 1rem; font-family: var(--font-body);
    width: 100%;
}
.field textarea { resize: vertical; min-height: 96px; line-height: 1.5; }
.field select {
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    cursor: pointer; padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23888' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 14px center;
}
/* native option list follows the OS, so force a dark, legible palette */
.field select option { background: var(--c-bg-raise); color: var(--c-text); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--c-blue); }
.form-msg { border-radius: 12px; padding: 12px 14px; font-size: .92rem; margin: 4px 0 14px; }
.form-msg.err { background: color-mix(in srgb, #f2565f 16%, transparent); color: #ff9aa0; border: 1px solid rgba(242,86,95,.4); }
.form-msg.ok { background: color-mix(in srgb, var(--c-ok) 16%, transparent); color: #9af0c4; border: 1px solid rgba(69,214,143,.4); }
.form-msg.warn { background: color-mix(in srgb, #f5a623 16%, transparent); color: #ffd28a; border: 1px solid rgba(245,166,35,.45); font-weight: 600; }
.form-alt { text-align: center; color: var(--c-text-dim); font-size: .92rem; margin-top: 16px; }
.form-alt a { color: var(--c-blue); font-weight: 600; }

/* Refused submit (Marc's rule 2026-10-27): the faulty field is marked and its
   message sits right under the control (UcFieldErr); editing clears both. */
.field.is-invalid:not(.is-edited) :is(input:not([type=checkbox]):not([type=radio]), select, textarea) {
    border-color: var(--c-bad, #ff4d5a); box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-bad, #ff4d5a) 22%, transparent);
}
.field.is-invalid:not(.is-edited) .choice { color: var(--c-bad-ink, #ff9aa0); }
.field-err { display: flex; gap: 7px; align-items: flex-start; margin-top: 2px; font-size: .88rem; font-weight: 600; line-height: 1.4; color: var(--c-bad-ink, #ff9aa0); }
.field-err::before { content: "!"; flex: none; display: grid; place-items: center; width: 17px; height: 17px; margin-top: 1px; border-radius: 50%; font-size: .72rem; font-weight: 800; background: var(--c-bad, #ff4d5a); color: #fff; }
.field.is-edited .field-err { display: none; }
html[data-site-theme="clear"] { --c-bad: #d42a3a; --c-bad-ink: #b3202f; }

/* inline radio/checkbox rows (cancellation form) */
.field .choice { display: flex; align-items: center; gap: 10px; font-size: .95rem; color: var(--c-text); font-weight: 400; cursor: pointer; padding: 4px 0; }
.field .choice input { width: auto; accent-color: var(--c-blue); margin: 0; }

/* read-back summary the visitor can save/print (cancellation receipt) */
.cancel-summary { border: 1px solid var(--c-border); border-radius: 12px; padding: 4px 16px; margin: 14px 0; background: var(--c-surface); }
.cancel-summary .row { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--c-border); font-size: .93rem; }
.cancel-summary .row:last-child { border-bottom: none; }
.cancel-summary .row span { color: var(--c-text-dim); white-space: nowrap; }
.cancel-summary .row b { text-align: right; word-break: break-word; }

/* payment iframe */
/* The gateway is a whole payment page: card fields, then the wallet buttons
   (Google Pay, and Apple Pay on an iPhone), then the payment details. At the
   panel's normal 460px it rendered as a narrow column with its own scrollbar
   and the wallet buttons fell below the fold, so the checkout widens its panel
   and the frame is tall enough to show the lot. Cross-origin content cannot be
   measured from here, so the height is deliberately generous: spare white space
   at the bottom is better than a second scrollbar over a payment form. */
.panel-page:has(.pay-frame) { max-width: 720px; }
.pay-frame { width: 100%; height: 1150px; border: 0; border-radius: var(--radius); background: #fff; }

@media (max-width: 640px) {
    /* Narrow screens stack every Redsys row, which needs noticeably more room. */
    .pay-frame { height: 1320px; }
}
.pay-methods { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
.pay-method { flex: 1; min-width: 130px; padding: 14px; border-radius: 12px; border: 1px solid var(--c-border); background: var(--c-surface); cursor: pointer; text-align: center; font-weight: 600; }
.pay-method.active { border-color: var(--c-blue); background: color-mix(in srgb, var(--c-blue) 18%, var(--c-surface)); }
/* 2026-10-03 (model app CCW): the wallet and "Card" side by side, two equal choices. */
.pay-choice { display: flex; gap: 12px; flex-wrap: wrap; }
.pay-choice .btn { flex: 1 1 160px; }
.btn-wallet { background: var(--c-wallet-bg); color: var(--c-wallet-fg); border-color: var(--c-wallet-bg);
    font-family: -apple-system, 'SF Pro Text', Roboto, sans-serif; font-weight: 600; font-size: 1.2rem; }
.btn-wallet:hover { opacity: .9; }
.btn-bizum { background: var(--c-bizum-bg); color: var(--c-bizum-fg); border-color: var(--c-bizum-bg); font-weight: 800; font-size: 1.2rem; }
.btn-bizum:hover { opacity: .9; }
.pay-summary { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 18px; padding-bottom: 16px; border-bottom: 1px solid var(--c-border); }
.pay-total { font-family: var(--font-display); font-size: 1.7rem; font-weight: 800; }
.spinner { width: 20px; height: 20px; border: 2px solid rgba(255,255,255,.25); border-top-color: #fff; border-radius: 50%; display: inline-block; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- legal / discount ---------- */
.legal-page { max-width: 760px; margin: 0 auto; padding: clamp(48px, 8vw, 96px) 20px; }
/* Obfuscated company name — assembled from two pseudo-element fragments so the
   name never exists as one indexable string in HTML, DOM or CSS. */
.co-name { font-weight: 700; color: var(--c-text); white-space: nowrap; }
.co-name::before { content: "EB"; }
.co-name::after { content: "OX3"; }
.legal-notice {
    border: 1px solid var(--c-border-strong); border-radius: var(--radius);
    background: var(--c-surface); padding: 18px 20px; margin: 18px 0 30px;
    font-size: .92rem;
}
.legal-notice p { margin: 0 0 10px; }
.legal-notice p:last-child { margin-bottom: 0; }
.legal-notice .ln-lang { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .1em; color: var(--c-cyan); margin-right: 8px; }
.legal-page h2 { color: var(--c-text); }
.legal-meta { color: var(--c-text-faint); font-size: .88rem; margin-bottom: 26px; }
.legal-title { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; margin-bottom: 8px; }
.legal-page h2 { font-size: 1.3rem; margin: 28px 0 8px; }
.legal-page p, .legal-page li { color: var(--c-text-dim); }
.disc-code-box { font-family: var(--font-mono); font-size: 1.6rem; letter-spacing: .1em; text-align: center; background: var(--c-surface-2); border: 1px dashed var(--c-border-strong); border-radius: 14px; padding: 18px; margin: 22px 0; color: var(--c-cyan); }

/* ---------- language dropdown ---------- */
.site-lang { position: relative; }
.site-lang > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border: 1px solid var(--c-border); border-radius: 999px; color: var(--c-text-dim); font-size: .88rem; font-weight: 600; }
.site-lang > summary::-webkit-details-marker { display: none; }
.site-lang-menu { position: absolute; right: 0; top: calc(100% + 8px); background: #10151f; border: 1px solid var(--c-border); border-radius: 12px; padding: 6px; min-width: 150px; box-shadow: var(--shadow-card); z-index: 50; }
.site-lang-item { display: block; padding: 8px 12px; border-radius: 8px; color: var(--c-text-dim); font-size: .92rem; }
.site-lang-item:hover { background: var(--c-surface-2); color: var(--c-text); }
.site-lang-item.active { color: var(--c-blue); font-weight: 700; }

/* ---------- footer ---------- */
.site-footer { border-top: 1px solid var(--c-border); padding: 32px clamp(16px, 4vw, 40px); }
.footer-inner { max-width: var(--maxw); margin: 0 auto; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; color: var(--c-text-faint); font-size: .88rem; }
.footer-links { display: flex; gap: 14px; flex-wrap: wrap; }
.footer-links a { color: var(--c-text-dim); }
.footer-links a:hover { color: var(--c-text); }

/* ---------- scroll reveal ---------- */
[data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .7s var(--ease-out), transform .7s var(--ease-out); transition-delay: var(--reveal-delay, 0s); }
[data-reveal].is-revealed { opacity: 1; transform: none; }
html:not(.js-on) [data-reveal] { opacity: 1; transform: none; }

/* ---------- hero demo video (UcPromoVideo): copy on top, then the clip; vertical cut on phones ---------- */
:root { --c-video-bg: #000000; }
.hero.hero-video { grid-template-columns: 1fr; min-height: auto; text-align: center; gap: clamp(28px, 4vw, 48px); }
.hero-video .hero-sub { margin-left: auto; margin-right: auto; max-width: 760px; }
.hero-video .hero-actions { justify-content: center; }
.promo-video { width: 100%; max-width: 1180px; margin: 0 auto; animation: rise-in .8s var(--ease-out) .3s backwards; }
.promo-frame { position: relative; margin: 0 auto; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--c-border-strong); box-shadow: var(--shadow-card), 0 0 70px var(--c-glow-cyan); background: var(--c-video-bg); }
.promo-h { aspect-ratio: 16 / 9; }
.promo-v { aspect-ratio: 9 / 16; width: min(100%, calc(80vh * 9 / 16)); display: none; }
.promo-clip { display: block; width: 100%; height: 100%; object-fit: cover; background: var(--c-video-bg); }
/* The clip itself opens full screen (site.js goFull); there the whole frame shows, never cropped. */
.promo-clip { cursor: pointer; }
.promo-clip:fullscreen { object-fit: contain; background: #000; cursor: auto; }
.promo-clip:-webkit-full-screen { object-fit: contain; background: #000; cursor: auto; }
.promo-play { position: absolute; left: 50%; top: 50%; width: 84px; height: 84px; margin: -42px 0 0 -42px; border-radius: 50%; border: 0; cursor: pointer;
    display: grid; place-items: center; background: var(--c-cyan); color: var(--c-bg); box-shadow: 0 0 40px var(--c-glow-cyan); transition: transform .2s var(--ease-out); }
.promo-play[hidden] { display: none; }
.promo-play:hover { transform: scale(1.06); }
.promo-full { position: absolute; right: 14px; bottom: 14px; width: 44px; height: 44px; border-radius: 12px; cursor: pointer; display: grid; place-items: center;
    background: color-mix(in srgb, var(--c-video-bg) 55%, transparent); color: var(--c-text); border: 1px solid var(--c-border-strong); }
.promo-full:hover { border-color: var(--c-cyan); }
:is(.promo-play, .promo-full):focus-visible { outline: 3px solid var(--c-cyan); outline-offset: 3px; }
/* must match UcPromoVideo VERT_MEDIA */
@media (max-width: 900px) and (orientation: portrait) {
    .promo-h { display: none; }
    .promo-v { display: block; }
}
/* phone: title, video, buttons, then the text */
@media (max-width: 900px) {
    .hero-video { display: flex; flex-direction: column; }
    .hero-video .hero-copy { display: contents; }
    .hero-video .hero-eyebrow { order: 1; margin-bottom: 0; }
    .hero-video .hero-title { order: 2; }
    .hero-video .promo-video { order: 3; }
    .hero-video .hero-actions { order: 4; }
    .hero-video .hero-sub { order: 5; margin: 0 auto; }
    .hero-video .hero-note { order: 6; margin-top: 0; }
    .promo-frame { border-radius: var(--radius); }
}
@media (prefers-reduced-motion: reduce) { .promo-video { animation: none; } }

/* ---------- responsive ---------- */
/* Grid/flex children default to min-width:auto, which lets long content force
   the track wider than a phone screen — the other horizontal-scroll trigger. */
.hero > *, .grid-3 > *, .grid-4 > *, .pricing-grid > * { min-width: 0; }

@media (max-width: 900px) {
    .hero { grid-template-columns: 1fr; text-align: center; min-height: auto; }
    .hero-sub { margin-left: auto; margin-right: auto; }
    .hero-actions { justify-content: center; }
    .hero-visual { max-width: 420px; margin: 8px auto 0; }
    .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 820px) {
    /* mobile: collapse the nav behind a hamburger (CSS-only via #nav-toggle) */
    .nav-burger {
        display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
        margin-left: auto; width: 44px; height: 44px; padding: 11px; cursor: pointer;
        border-radius: 12px; border: 1px solid var(--c-border); background: var(--c-surface);
    }
    .nav-burger span { display: block; height: 2px; width: 100%; background: var(--c-text); border-radius: 2px; transition: transform .2s, opacity .2s; }
    .header-nav {
        position: absolute; top: 100%; left: 0; right: 0; margin: 0;
        display: none; flex-direction: column; align-items: stretch; gap: 4px;
        padding: 12px clamp(16px, 4vw, 40px) 20px;
        background: color-mix(in srgb, var(--c-bg) 92%, transparent);
        backdrop-filter: saturate(160%) blur(16px); -webkit-backdrop-filter: saturate(160%) blur(16px);
        border-bottom: 1px solid var(--c-border); box-shadow: var(--shadow-card);
    }
    #nav-toggle:checked ~ .header-nav { display: flex; }
    .header-link { display: block; padding: 11px 4px; font-size: 1.05rem; }
    .header-actions { flex-direction: column; align-items: stretch; gap: 10px; margin-top: 10px; }
    .header-actions .btn { width: 100%; }
    .site-lang { align-self: stretch; margin: 4px 0; }
    .site-lang > summary { width: max-content; }
    /* in the hamburger panel the language list flows inline instead of an off-screen popover */
    .site-lang-menu { position: static; right: auto; top: auto; min-width: 0; margin-top: 6px; padding: 4px 0 0; background: transparent; border: none; box-shadow: none; }
    .site-lang-item { padding: 10px 8px; font-size: 1rem; }
    #nav-toggle:checked ~ .nav-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    #nav-toggle:checked ~ .nav-burger span:nth-child(2) { opacity: 0; }
    #nav-toggle:checked ~ .nav-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}
@media (max-width: 560px) {
    .grid-3, .grid-4 { grid-template-columns: 1fr; }
    .footer-inner { flex-direction: column; }
}
/* ============================================================
   MOTION — "light follows you". One orchestrated load moment
   (the hero lights up like a house at dusk) plus one signature
   interaction (a cursor spotlight over cards). All colours come
   from theme variables so every theme keeps working.
   ============================================================ */

/* page-load orchestration: hero copy rises in, the home lights up */
@keyframes rise-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes lights-on { 0% { filter: brightness(.22) saturate(.55); } 65% { filter: brightness(1.07) saturate(1.06); } 100% { filter: brightness(1) saturate(1); } }
@keyframes glow-bloom { from { opacity: 0; } to { opacity: 1; } }
.hero-eyebrow, .hero-title, .hero-sub, .hero-actions, .hero-note { animation: rise-in .7s var(--ease-out) backwards; }
.hero-title { animation-delay: .08s; }
.hero-sub { animation-delay: .16s; }
.hero-actions { animation-delay: .24s; }
.hero-note { animation-delay: .34s; }
.hero-img { animation: lights-on 1.6s ease-out .35s backwards; }
.hero-img-glow { animation: glow-bloom 1.9s ease-out .55s backwards; }

/* Slide-in elements are hidden from the FIRST paint (browsers paint
   progressively before end-of-body scripts run — JS-only hiding flashes the
   content once before the animation). The head sets .js-on pre-paint; without
   JS the content just shows. The animator restores opacity inline when done. */
html.js-on [data-slide] { opacity: 0; }

/* Embedded in the mobile app: belt and braces next to the two guards above
   (no .js-on in embed mode, site.js bails out) — nothing may ever be hidden
   waiting for an animation that will not run inside the app's frame. */
html.embed [data-slide],
html.embed [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
}

/* signature: a pool of light tracks the pointer across cards */
.card, .price-card { position: relative; overflow: hidden; }
.card::after, .price-card::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(230px circle at var(--mx, 50%) var(--my, 42%), var(--c-glow-blue), transparent 68%);
    opacity: 0; transition: opacity .35s;
}
.card:hover::after, .price-card:hover::after { opacity: .5; }

/* the recommended plan breathes softly, like the lit room of the house */
@keyframes featured-breathe {
    0%, 100% { box-shadow: 0 0 0 1px var(--c-glow-blue), 0 0 24px var(--c-glow-blue); }
    50% { box-shadow: 0 0 0 1px var(--c-glow-cyan), 0 0 46px var(--c-glow-blue); }
}
.price-card.featured { animation: featured-breathe 4.5s ease-in-out infinite; }

/* primary buttons: a light sweep crosses on hover */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -70%; width: 44%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .32), transparent);
    transform: skewX(-18deg); transition: left .55s ease;
}
.btn-primary:hover::after { left: 125%; }

/* Reduced motion only stills the ambient background — content animations always
   play, matching the REYSTI model app (Windows' "Show animations" off / RDP
   sessions report reduced motion and would otherwise hide them entirely). */
@media (prefers-reduced-motion: reduce) {
    .bg-grid, .bg-aurora { animation: none; }
}

/* ---------- theme picker (dev/pre-launch) ---------- */
.theme-picker { position: fixed; right: 14px; bottom: 14px; z-index: 60; display: flex; gap: 6px; padding: 8px; border-radius: 999px; background: color-mix(in srgb, var(--c-bg) 70%, transparent); border: 1px solid var(--c-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); box-shadow: var(--shadow-card); }
.theme-dot { width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; display: block; }
.theme-dot.active { border-color: #fff; }
.theme-dot.obsidian { background: linear-gradient(135deg, #8b3dff, #00e5ff); }
.theme-dot.midnight { background: linear-gradient(135deg, #5b9dff, #40c9ff); }
.theme-dot.aurora { background: linear-gradient(135deg, #2dd4bf, #4ade80); }
.theme-dot.sunset { background: linear-gradient(135deg, #ffb454, #ff5c8a); }
.theme-dot.ember { background: linear-gradient(135deg, #ff8c1a, #ffc857); }
@media (max-width: 560px) { .theme-picker { bottom: 10px; right: 10px; } }

/* ---------- account page (PgAccount) ----------
   /account is a dashboard, not a form: on a desktop screen the shared 460px
   panel left the page empty either side and pushed the content into one long
   scroll. The account panel therefore widens, and the short read-out sections
   (.acct-cols) flow into 2 columns from 900px and 3 from 1500px. A CSS
   multi-column, not a grid, on purpose: the sections differ a lot in height and
   a grid would align them by row and leave holes, while a multi-column balances
   them. The blocks that need the whole width (history table, plan picker, the
   gateway iframe while the card is being replaced) sit in .acct-full between
   them. Below 900px everything is the single stacked column it has always
   been. */

.acct-page { max-width: 1240px; }
/* wins over .panel-page:has(.pay-frame) above, which shrinks a checkout panel */
.acct-page:has(.pay-frame) { max-width: 1240px; }

.acct-cols > .acct-sec { break-inside: avoid; }

/* the picker is not in a 460px column here, so it keeps the marketing sizes */
.acct-page .panel-card .pricing-grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.acct-page .panel-card .price-card { padding: 24px; }

@media (min-width: 900px) {
    .acct-cols { column-count: 2; column-gap: 32px; }
    /* a column break can land anywhere, so every section carries its own
       spacing instead of relying on the heading's top margin */
    .acct-cols > .acct-sec { margin-bottom: 24px; }
    .acct-cols > .acct-sec > .panel-section { margin-top: 0; }
    .acct-cols2 { column-count: 2; }
    /* the columns' own top margins are gone, so the block carries the gap */
    .acct-full + .acct-cols { margin-top: 26px; }
    /* a password field or a link stack stays a form-sized control, not a
       1000px-wide input, even though its column is that wide */
    .acct-cols2 .field, .acct-cols2 .acct-links, .acct-cols2 > .acct-sec > .btn-block { max-width: 420px; }
}

@media (min-width: 1500px) {
    .acct-cols { column-count: 3; }
    .acct-cols2 { column-count: 2; }
}

.panel-section {
    margin: 26px 0 10px;
    font-size: 1.02rem;
    font-weight: 700;
}

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

.acct-row {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    padding: 9px 12px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    font-size: 0.92rem;
}

    .acct-row span { opacity: 0.65; }

.acct-links { display: flex; flex-direction: column; gap: 8px; }

/* ---------- account panel: modules, renewal, card, history (2026-09-07) ---------- */
.mod-row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 12px; border: 1px solid var(--c-border); border-radius: 10px; font-size: 0.92rem;
}
    .mod-row .mod-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
    .mod-row .mod-name { font-weight: 600; }
    .mod-row .mod-status { font-size: 0.82rem; opacity: 0.65; }
    .mod-row.ending { border-color: #e8a33d; }
    .mod-row.ending .mod-status { color: #b9741a; opacity: 1; }
    .mod-row .btn { flex: 0 0 auto; }
.acct-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
    .acct-confirm .btn { width: auto; }

/* ---------- account panel: home server card (UcServerInstall, 2026-10-28) ----------
   While no server runs yet it is THE reason the customer is here: framed in
   the accent colour. Once a server is active it shrinks to the list. */
.srv-sec.srv-first {
    padding: 4px 18px 18px; border: 1px solid var(--c-blue); border-radius: 14px;
    box-shadow: 0 0 24px var(--c-glow-blue);
}
.srv-steps { margin-top: 10px; }
.srv-list li { color: var(--c-text); }
.srv-note { margin-top: 8px; font-size: .84rem; }
.srv-sub { margin: 20px 0 6px; font-size: .95rem; font-weight: 700; }

/* "Unblock the zip" step (2026-10-28): a drawn copy of the Windows file
   Properties window with the Unblock box highlighted. It depicts WINDOWS'
   own light dialog, so its greys are Windows', not the site theme's; the
   highlight uses the site accent. */
.srv-unblock-step strong { color: var(--c-text); }
.win-mock {
    max-width: 420px; margin: 10px 0 4px; border-radius: 8px; overflow: hidden;
    background: #f3f3f3; color: #1b1b1b; border: 1px solid #c9c9c9;
    font: 12px "Segoe UI", system-ui, sans-serif; box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
.win-mock-title { display: flex; justify-content: space-between; padding: 7px 10px; background: #ffffff; font-size: 12px; }
.win-mock-x { opacity: .6; }
.win-mock-tabs { padding: 0 10px; background: #ffffff; border-bottom: 1px solid #dcdcdc; }
.win-mock-tabs span { display: inline-block; padding: 5px 8px; border-bottom: 2px solid #005fb8; font-weight: 600; }
.win-mock-body { padding: 10px 12px; }
.win-mock-line { height: 7px; margin: 7px 0; border-radius: 4px; background: #dedede; width: 85%; }
.win-mock-line.short { width: 55%; }
.win-mock-sec {
    display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; align-items: start;
    margin-top: 12px; padding-top: 10px; border-top: 1px solid #dcdcdc;
}
.win-mock-label { font-weight: 600; }
.win-mock-sectext { line-height: 1.35; }
.win-mock-check {
    grid-column: 2; justify-self: end; display: inline-flex; align-items: center; gap: 6px;
    margin-top: 4px; padding: 3px 8px; border-radius: 6px; font-weight: 700;
    outline: 3px solid var(--c-cyan); box-shadow: 0 0 14px var(--c-glow-cyan);
    animation: srv-unblock-pulse 1.6s ease-in-out infinite;
}
.win-mock-check .box {
    width: 14px; height: 14px; border-radius: 3px; background: #005fb8; color: #ffffff;
    display: inline-flex; align-items: center; justify-content: center; font-size: 10px;
}
@keyframes srv-unblock-pulse { 0%, 100% { box-shadow: 0 0 6px var(--c-glow-cyan); } 50% { box-shadow: 0 0 18px var(--c-glow-cyan); } }
.win-mock-btns { display: flex; justify-content: flex-end; gap: 8px; padding: 8px 12px 10px; }
.win-mock-btn { min-width: 62px; text-align: center; padding: 4px 10px; border-radius: 4px; background: #fdfdfd; border: 1px solid #c9c9c9; }
.win-mock-btn.ok { background: #005fb8; border-color: #005fb8; color: #ffffff; outline: 2px solid var(--c-cyan); outline-offset: 2px; }
.srv-unblock-cap { font-size: .84rem; color: var(--c-text-dim); margin-bottom: 4px; }

/* "If Windows blocks the installation" fold-out (Smart App Control). */
.srv-sac {
    margin: 4px 0 14px; padding: 10px 14px; border-radius: 10px;
    border: 1px solid var(--c-border); background: var(--c-surface);
}
.srv-sac summary { cursor: pointer; font-weight: 600; color: var(--c-text); }
.srv-sac p { margin: 8px 0 0; font-size: .88rem; color: var(--c-text-dim); line-height: 1.45; }
.srv-sac .form-msg { margin-top: 10px; font-size: .86rem; }
@media (prefers-reduced-motion: reduce) { .win-mock-check { animation: none; } }

/* Download status, right above the button: preparing (pulsing orb + sliding
   bar), sending (real percentage), ready, failed. */
.srv-dl {
    margin: 6px 0 12px; padding: 14px 16px; border-radius: 12px;
    border: 1px solid var(--c-cyan); background: var(--c-surface);
    box-shadow: 0 0 18px var(--c-glow-cyan);
}
.srv-dl.ready { border-color: var(--c-ok); box-shadow: none; }
.srv-dl.failed { border-color: #e8a33d; box-shadow: none; }
.srv-dl-head { display: flex; align-items: center; gap: 12px; font-size: .98rem; }
.srv-dl p { margin: 8px 0 0; font-size: .88rem; color: var(--c-text-dim); line-height: 1.45; }
.srv-dl-orb {
    flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
    background: var(--c-cyan); box-shadow: 0 0 0 0 var(--c-glow-cyan);
    animation: srv-orb 1.4s ease-out infinite;
}
@keyframes srv-orb {
    0% { transform: scale(.8); box-shadow: 0 0 0 0 var(--c-glow-cyan); }
    60% { transform: scale(1); box-shadow: 0 0 0 12px transparent; }
    100% { transform: scale(.8); box-shadow: 0 0 0 0 transparent; }
}
.srv-dl-ok, .srv-dl-bad {
    flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: .85rem; color: var(--c-bg);
}
.srv-dl-ok { background: var(--c-ok); }
.srv-dl-bad { background: #e8a33d; }
.srv-dl-bar {
    position: relative; height: 8px; margin-top: 12px; border-radius: 999px;
    background: var(--c-border); overflow: hidden;
}
.srv-dl-bar > span {
    position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 999px;
    background: linear-gradient(90deg, var(--c-blue), var(--c-cyan));
    transition: width .8s ease;
}
/* No byte count yet: a segment sliding back and forth says "working". */
.srv-dl.preparing .srv-dl-bar > span { width: 35%; animation: srv-slide 1.3s ease-in-out infinite; }
.srv-dl.sending .srv-dl-bar > span:not([style]) { width: 35%; animation: srv-slide 1.3s ease-in-out infinite; }
@keyframes srv-slide { 0% { left: -35%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) {
    .srv-dl-orb, .srv-dl.preparing .srv-dl-bar > span, .srv-dl.sending .srv-dl-bar > span:not([style]) { animation: none; }
}
.pay-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
    .pay-table th, .pay-table td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--c-border); }
    .pay-table th { font-weight: 600; opacity: 0.7; }
    .pay-table td.amt { text-align: right; white-space: nowrap; }
    .pay-table .st-ok { color: #2f9e5b; }
    .pay-table .st-failed { color: #c2483b; }
    .pay-table .st-refunded { color: #b9741a; }
.acct-wrap { overflow-x: auto; }

/* ---------- interactive plan picker (signed-in surfaces: /account, /subscribe) ----------
   Same look as the marketing pricing switch, but driven by Blazor rather than
   the CSS-only radios (those only work inside the statically rendered page). */
.plan-toggle {
    display: flex; width: max-content; gap: 4px; margin: 22px auto 0; padding: 5px;
    border: 1px solid var(--c-border); border-radius: 999px; background: var(--c-surface);
}

    .plan-toggle button {
        display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
        padding: 9px 20px; border: 0; border-radius: 999px; background: transparent;
        font-family: inherit; font-weight: 600; font-size: .95rem;
        color: var(--c-text-dim); transition: background .2s, color .2s;
    }

        .plan-toggle button.on { background: var(--c-blue); color: #fff; }

        .plan-toggle button.on .save-badge { background: rgba(255,255,255,.22); color: #fff; }

/* Inside a panel the cards must stay compact: the checkout column is narrow. */
.panel-card .pricing-grid { margin-top: 18px; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.panel-card .price-card { padding: 20px; }
.panel-card .price-amount { font-size: 1.6rem; }

/* The plan the customer is already on: shown as a flat marker, never clickable. */
.btn.is-current {
    cursor: default; opacity: .7;
    border-style: dashed;
    pointer-events: none;
}

/* the two-way switches wrap on a narrow panel instead of overflowing it */
.plan-toggle { max-width: 100%; flex-wrap: wrap; justify-content: center; }
.plan-toggle.acct-choice { margin-top: 16px; }

/* "/ month" suffix next to a payment total */
.pay-per { font-size: .9rem; font-weight: 400; opacity: .6; }

/* ---------- basket ---------- */
.cart-lines { display: flex; flex-direction: column; gap: 8px; margin: 14px 0 18px; }

.cart-line {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--c-border); border-radius: 12px;
    background: var(--c-surface-2);
    font-size: .95rem;
}

    .cart-line .cart-name { flex: 1; min-width: 0; font-weight: 600; }

    .cart-line .cart-per { display: block; font-weight: 400; font-size: .8rem; color: var(--c-text-dim); }

    .cart-line .cart-amount { font-weight: 700; white-space: nowrap; }

.cart-qty { display: inline-flex; align-items: center; gap: 4px; }

    .cart-qty button {
        width: 26px; height: 26px; line-height: 1; cursor: pointer;
        border: 1px solid var(--c-border); border-radius: 8px;
        background: var(--c-surface); color: var(--c-text); font-family: inherit; font-size: 1rem;
    }

    .cart-qty span { min-width: 20px; text-align: center; font-weight: 700; }

.cart-remove {
    border: 0; background: transparent; cursor: pointer;
    color: var(--c-text-dim); font-size: 1.3rem; line-height: 1; padding: 0 2px;
}

    .cart-remove:hover { color: var(--c-text); }

/* "add another plan or module" disclosure on the checkout */
.cart-more { margin: 6px 0 18px; }

    .cart-more > summary {
        cursor: pointer; padding: 10px 0; font-weight: 600; color: var(--c-blue);
    }

/* basket line in read-only mode (the payment step) */
.cart-qty-flat { color: var(--c-text-dim); font-size: .9rem; }

/* the checkout waits here while the browser stores are read back */
.panel-loading { display: flex; justify-content: center; padding: 40px 0; }

/* ==================== ACCOUNT: reactivate a locked home ====================
   Shown when the subscription is not running, i.e. when the home SERVER has
   stopped driving the house (2026-09-09). Deliberately not alarming red: it
   states facts and offers the way back. */
.acct-react {
    border-left: 3px solid var(--c-blue);
}

.react-list {
    margin: 8px 0 14px; padding-left: 20px;
    color: var(--c-text-dim); font-size: .92rem; line-height: 1.5;
}

    .react-list li { margin: 4px 0; }

/* ==================== INTEGRATORS LANDING (/integrators) ==================== */
.int-you-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 28px; align-items: center; margin-top: 24px; }
.int-points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.int-points li { color: var(--c-text-dim); line-height: 1.5; padding-left: 18px; border-left: 2px solid var(--c-cyan); }
.int-points li strong { color: var(--c-text); display: block; margin-bottom: 2px; }
.int-rates { display: flex; gap: 14px; flex-wrap: wrap; }
.int-rate { flex: 1 1 140px; padding: 22px; border-radius: var(--radius); border: 1px solid var(--c-border); background: var(--c-surface); text-align: center; }
.int-rate-num { font-size: 2.4rem; font-weight: 800; line-height: 1; }
.int-rate-label { color: var(--c-text-dim); margin-top: 8px; font-weight: 600; }
.int-fine { color: var(--c-text-faint); font-size: .9rem; margin-top: 22px; }
.int-fine a { color: var(--c-blue); font-weight: 600; }
.int-stores { display: flex; gap: 14px; justify-content: center; align-items: center; flex-wrap: wrap; margin-top: 26px; }
/* Official store badges: one height for both, never stretched (width:auto). */
/* Both store buttons are the SAME size (Marc 2026-10-27): the stores' own logo and
   lettering (img/stores, the official artwork with its frame removed) centred in one
   shared frame drawn here, in the badges' own black and #a6a6a6 edge. */
.store-badge {
    display: flex; align-items: center; justify-content: center;
    width: 184px; height: 56px; border-radius: 10px; line-height: 0;
    background: #000000; border: 1px solid #a6a6a6;
    transition: transform .2s var(--ease-out), box-shadow .2s;
}
.store-badge img { display: block; height: 52px; width: auto; max-width: 100%; }
.store-badge:hover { transform: translateY(-2px); box-shadow: 0 0 0 2px var(--c-border-strong), 0 8px 22px rgba(0, 0, 0, 0.35); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .store-badge:hover { box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-aqua) 70%, transparent), 0 0 18px var(--c-glow-cyan); }
.int-call { max-width: 760px; margin: 0 auto; }
.int-call-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; margin-top: 18px; }
@media (max-width: 720px) {
    .int-you-grid, .int-call-grid { grid-template-columns: 1fr; }
}
/* Funnel (2026-10-30): video first, one button under it, the same button after each block. */
.int-hero-after { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.int-hero-after .hero-sub { margin: 18px auto 0; }
.int-hero-after .hero-note { margin-top: 0; }
.int-cta-note { color: var(--c-text-faint); font-size: .92rem; }
.int-cta-row { text-align: center; margin-top: 30px; }
@media (max-width: 900px) {
    .hero-video .int-hero-after { order: 4; }
}
.int-diff { max-width: 980px; margin: 0 auto; }
.int-diff-list { margin: 22px 0 0; padding-left: 1.4em; display: flex; flex-direction: column; gap: 14px; color: var(--c-text-dim); line-height: 1.55; }
.int-diff-list li::marker { color: var(--c-cyan); font-weight: 800; }
.int-diff-list strong { color: var(--c-text); }
.int-diff-foot { margin-top: 24px; font-weight: 700; color: var(--c-text); }
.int-table-wrap { overflow-x: auto; margin-top: 26px; border-radius: var(--radius); border: 1px solid var(--c-border); }
.int-table { width: 100%; border-collapse: collapse; min-width: 560px; }
.int-table th, .int-table td { padding: 14px 18px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--c-border); line-height: 1.45; }
.int-table th { color: var(--c-text-faint); font-size: .85rem; text-transform: uppercase; letter-spacing: .06em; background: var(--c-surface); }
.int-table td { color: var(--c-text-dim); }
.int-table td:first-child { color: var(--c-text); font-weight: 700; }
.int-table tr:last-child td { border-bottom: 0; }
.int-row-odo td { background: color-mix(in srgb, var(--c-cyan) 10%, transparent); color: var(--c-text); font-weight: 600; }
.int-choice { margin-top: 26px; padding: 20px 22px; border-radius: var(--radius); border: 1px solid var(--c-border); background: var(--c-surface); }
.int-choice p { color: var(--c-text-dim); margin: 8px 0 0; line-height: 1.55; }
.int-faq { max-width: 860px; display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }
.int-faq-item { border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-surface); }
.int-faq-item summary { cursor: pointer; padding: 16px 20px; font-weight: 700; color: var(--c-text); list-style: none; }
.int-faq-item summary::-webkit-details-marker { display: none; }
.int-faq-item summary::after { content: "+"; float: right; color: var(--c-cyan); font-weight: 800; }
.int-faq-item[open] summary::after { content: "\2212"; }
.int-faq-item p { margin: 0; padding: 0 20px 18px; color: var(--c-text-dim); line-height: 1.55; }
.int-after-ok { color: var(--c-text-dim); margin-top: 16px; text-align: center; }
/* the form right under the hero: the sticky header must not hide its title after a booking button */
.int-call-section { scroll-margin-top: calc(var(--header-h) + 16px); padding-top: clamp(24px, 4vw, 48px); }
.site-header-landing .site-lang { margin-left: auto; align-self: center; }
/* on phones the selector is NOT in a burger panel here: keep the popover (overrides the mobile inline list) */
.site-header-landing .site-lang-menu { position: absolute; right: 0; top: calc(100% + 8px); min-width: 150px; padding: 6px; margin-top: 0;
    background: var(--c-bg-raise, #10151f); border: 1px solid var(--c-border); border-radius: 12px; box-shadow: var(--shadow-card); }
.site-header-landing .site-lang-item { padding: 8px 12px; font-size: .92rem; }

/* ==================== PARTNER LANDING (/p/{code}, white-label QR) ==================== */
.pa-hero { grid-template-columns: 1fr; text-align: center; min-height: auto; }
.pa-hero .hero-title { margin-inline: auto; }
.pa-logo { display: block; max-width: min(320px, 80%); width: auto; height: auto; max-height: 120px; margin: 0 auto 22px; object-fit: contain; }
.pa-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.pa-code { margin-top: 14px; font-family: var(--font-mono); font-size: .85rem; color: var(--c-text-dim); letter-spacing: .06em; user-select: all; }
@media (max-width: 900px) { #pa-steps .grid-3 { grid-template-columns: 1fr; } }

/* ============================================================================
   CARBON BLACK (default) + CLEAR, cloned from the CASASAC app (2026-10-27).
   The APP's own material instead of a marketing skin: black moulded-plastic
   panes with a hard gloss line at 42 % of their height, lit aqua keys
   (#19e6ea, the colour of the O-DOMO logo) and the app's seamless carbon twill
   tile as the ground. CLEAR is its light sibling: white glazed porcelain, the
   same aqua, deepened wherever it is text.
   Signature: the weave CATCHES THE LIGHT. A diagonal sweep crosses it once on
   load while the hero photo switches on, then a specular pool follows the
   pointer (site.js initSheen; it drifts on its own on touch screens).
   Everything below is scoped to these two themes: the five older palettes
   above render exactly as before.
   Fonts bundled locally (no CDN): Bricolage Grotesque (display, condensed
   widths) + IBM Plex Mono (labels, figures), the CASASAC site's pair.
   ============================================================================ */

@font-face { font-family: "Bricolage Grotesque"; src: url("fonts/BricolageGrotesque-var.woff2") format("woff2"); font-weight: 200 800; font-stretch: 75% 100%; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-400-latin.woff2") format("woff2"); font-weight: 400; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-400-latin-ext.woff2") format("woff2"); font-weight: 400; font-display: swap; unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-500-latin.woff2") format("woff2"); font-weight: 500; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-500-latin-ext.woff2") format("woff2"); font-weight: 500; font-display: swap; unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-600-latin.woff2") format("woff2"); font-weight: 600; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-600-latin-ext.woff2") format("woff2"); font-weight: 600; font-display: swap; unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* ---------- THEME: CARBON BLACK ---------- */
html[data-site-theme="carbon"] {
    --c-bg: #050707; --c-bg-raise: #0d1112; --c-pane: #0c0f10;
    --c-surface: rgba(255, 255, 255, 0.045); --c-surface-2: rgba(255, 255, 255, 0.085);
    --c-well: rgba(0, 0, 0, 0.42);
    --c-border: rgba(255, 255, 255, 0.13); --c-border-strong: rgba(255, 255, 255, 0.26);
    --c-text: #eef4f4; --c-text-dim: rgba(238, 244, 244, 0.68); --c-text-faint: rgba(238, 244, 244, 0.46);

    /* --c-blue / --c-cyan = the accent wherever it is TEXT or a line;
       --c-aqua = the lit key itself, --c-on-aqua = the label printed on it. */
    --c-blue: #19e6ea; --c-blue-deep: #11b9bd; --c-cyan: #19e6ea; --c-cyan-soft: #8ff4f6;
    --c-glow-blue: rgba(25, 230, 234, 0.34); --c-glow-cyan: rgba(25, 230, 234, 0.2);
    --c-aqua: #19e6ea; --c-on-aqua: #00191a;
    --c-ok: #45d68f;

    /* lit text: aqua with a white glint travelling through it */
    --grad-brand: linear-gradient(100deg, #19e6ea 0%, #19e6ea 36%, #e6feff 48%, #19e6ea 60%, #19e6ea 100%);
    --shadow-btn: 0 0 14px rgba(25, 230, 234, 0.4);
    --shadow-card: 0 18px 48px rgba(0, 0, 0, 0.6);

    --gloss: linear-gradient(180deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.085) 42%, rgba(255, 255, 255, 0) 42.4%);
    --pane-hilite: inset 0 1px 0 rgba(255, 255, 255, 0.36), inset 0 -1px 0 rgba(0, 0, 0, 0.9);
    --key-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.12) 44%, rgba(255, 255, 255, 0.03) 45%, rgba(255, 255, 255, 0) 100%);
    --key-base: #121414;
    --key-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
    --twill-opacity: 0.5;
    /* the app's aqua accent on the carbon (CAS --cas-atmosphere, 2026-10-25) */
    --ground-glow: radial-gradient(75vw 60vh at 100% 0%, rgba(25, 230, 234, 0.14), transparent 72%);

    color-scheme: dark;
}

/* ---------- THEME: CLEAR (light) ---------- */
html[data-site-theme="clear"] {
    --c-bg: #e6edef; --c-bg-raise: #f5f8f9; --c-pane: #ffffff;
    --c-surface: rgba(255, 255, 255, 0.72); --c-surface-2: rgba(10, 42, 48, 0.055);
    --c-well: rgba(10, 42, 48, 0.05);
    --c-border: rgba(10, 42, 48, 0.15); --c-border-strong: rgba(10, 42, 48, 0.3);
    --c-text: #0b1518; --c-text-dim: rgba(11, 21, 24, 0.72); --c-text-faint: rgba(11, 21, 24, 0.54);

    --c-blue: #007c81; --c-blue-deep: #00666a; --c-cyan: #007c81; --c-cyan-soft: #19b9be;
    --c-glow-blue: rgba(25, 211, 216, 0.3); --c-glow-cyan: rgba(25, 211, 216, 0.18);
    --c-aqua: #19d3d8; --c-on-aqua: #00282a;
    --c-ok: #13a36a;
    --c-wallet-bg: #000000; --c-wallet-fg: #ffffff;

    --grad-brand: linear-gradient(100deg, #007c81 0%, #007c81 36%, #19c4c9 48%, #007c81 60%, #007c81 100%);
    --shadow-btn: 0 4px 14px rgba(25, 211, 216, 0.35);
    --shadow-card: 0 16px 40px rgba(10, 42, 48, 0.13);

    --gloss: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.7) 42%, rgba(255, 255, 255, 0) 42.4%);
    --pane-hilite: inset 0 1px 0 #ffffff, inset 0 -1px 0 rgba(10, 42, 48, 0.08);
    --key-bg: linear-gradient(180deg, #ffffff 0%, #f6f9fa 44%, #eaf0f2 45%, #e2e9eb 100%);
    --key-base: #ffffff;
    --key-shadow: 0 3px 10px rgba(10, 42, 48, 0.12);
    --twill-opacity: 0;
    --ground-glow:
        radial-gradient(900px 600px at 15% -10%, rgba(255, 255, 255, 0.95), transparent 60%),
        radial-gradient(700px 500px at 100% 100%, rgba(25, 211, 216, 0.12), transparent 60%),
        linear-gradient(180deg, #f2f6f7 0%, #e3eaec 100%);

    color-scheme: light;
}

/* ---------- shared tokens of the two material themes ---------- */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) {
    --font-display: "Bricolage Grotesque", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
    --radius: 18px;
    --radius-lg: 26px;
    --radius-key: 12px;
    --gloss-cap: 116px;
    --lit-bg: linear-gradient(180deg, color-mix(in srgb, var(--c-aqua) 58%, white) 0%, color-mix(in srgb, var(--c-aqua) 78%, white) 44%, var(--c-aqua) 45%, color-mix(in srgb, var(--c-aqua) 80%, black) 100%);
    --lit-glow: inset 0 1px 0 rgba(255, 255, 255, 0.6), inset 0 -1px 0 rgba(0, 0, 0, 0.3), 0 0 14px color-mix(in srgb, var(--c-aqua) 50%, transparent), 0 6px 20px color-mix(in srgb, var(--c-aqua) 28%, transparent);
}

/* The older themes never show the weave, its glow, sweep or sheen. */
.bg-twill, .bg-glow, .bg-sweep, .bg-flash, .bg-sheen { display: none; }

/* ---------- ground: carbon twill, its aqua accent and the light it catches ----------
   Every layer is position:fixed and painted ONCE. The sweep and the sheen move
   only by transform (compositor work, no repaint): the outer box carries a static
   mask and travels, its inner <i> holds the brightened weave and travels the
   opposite way, so the fibres stay locked to the viewport like the base twill. */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.bg-grid, .bg-aurora, #odo-stars) { display: none; }
html[data-site-theme="carbon"] :is(.bg-twill, .bg-glow, .bg-sweep, .bg-flash, .bg-sheen) { display: block; }
html[data-site-theme="clear"] .bg-glow { display: block; }

.bg-twill {
    position: fixed; inset: 0; z-index: -3; pointer-events: none;
    background: url("img/carbon-fibre.jpg") 0 0 / 72px 72px repeat;
    opacity: var(--twill-opacity);
    -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.3) 100%);
    mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.3) 100%);
}
/* The aqua accent of the app's ground (CAS --cas-atmosphere): a glow in the
   top-right corner over the weave. Clear: white light top-left, aqua bottom-right. */
.bg-glow { position: fixed; inset: 0; z-index: -2; pointer-events: none; background: var(--ground-glow); }

/* The brightened weave shared by the sweep and the sheen (inner layer). */
.bg-sweep, .bg-sheen { position: fixed; left: 0; top: 0; z-index: -1; pointer-events: none; will-change: transform; }
:is(.bg-sweep, .bg-sheen) > i {
    position: absolute; width: 100vw; height: 100vh; will-change: transform;
    background: url("img/carbon-fibre.jpg") 0 0 / 72px 72px repeat;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.3) 100%);
    mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.3) 100%);
}

/* The load sweep: a diagonal band of light crosses the weave on every page
   (a full load plays it; site.js replaySweep restarts it after an enhanced navigation). */
.bg-sweep {
    width: 140vw; height: 100vh;
    -webkit-mask-image: linear-gradient(115deg, transparent 38%, #000 50%, transparent 62%);
    mask-image: linear-gradient(115deg, transparent 38%, #000 50%, transparent 62%);
    transform: translate3d(100vw, 0, 0); opacity: 0;
    animation: sweep-box 2.4s cubic-bezier(.45, .05, .25, 1) .15s backwards;
}
.bg-sweep > i { left: 0; top: 0; opacity: var(--twill-opacity); filter: brightness(3.2) contrast(1.15); transform: translate3d(-100vw, 0, 0); animation: sweep-weave 2.4s cubic-bezier(.45, .05, .25, 1) .15s backwards; }
@keyframes sweep-box { from { transform: translate3d(-140vw, 0, 0); opacity: 1; } 85% { opacity: 1; } to { transform: translate3d(100vw, 0, 0); opacity: 0; } }
@keyframes sweep-weave { from { transform: translate3d(140vw, 0, 0); } to { transform: translate3d(-100vw, 0, 0); } }

/* The white flash (Marc 2026-10-27: "a flash when loading, keep it on every
   page, it can be white"): when the sweep reaches the top-right corner the
   weave flares white there, then settles into the resting sheen. Painted once;
   only its opacity animates. */
.bg-flash {
    position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
        radial-gradient(60vmax 45vmax at 80% 12%, rgba(255, 255, 255, 0.32), transparent 70%),
        url("img/carbon-fibre.jpg") 0 0 / 72px 72px repeat;
    filter: brightness(3.4) contrast(1.1);
    -webkit-mask-image: radial-gradient(70vmax 52vmax at 80% 12%, #000 0%, rgba(0, 0, 0, 0.55) 30%, transparent 72%);
    mask-image: radial-gradient(70vmax 52vmax at 80% 12%, #000 0%, rgba(0, 0, 0, 0.55) 30%, transparent 72%);
    opacity: 0;
    animation: weave-flash 1.7s cubic-bezier(.2, .7, .3, 1) 1.45s backwards;
}
@keyframes weave-flash { 0% { opacity: 0; } 14% { opacity: 1; } 100% { opacity: 0; } }

/* The specular pool under the pointer (site.js initSheen moves both layers);
   until the pointer moves, and on touch screens, it drifts on its own. */
.bg-sheen {
    width: 70vmax; height: 70vmax; margin: -35vmax 0 0 -35vmax;
    -webkit-mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, 0.45) 38%, transparent 72%);
    mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, 0.45) 38%, transparent 72%);
    opacity: .85;
    transform: translate3d(74vw, 18vh, 0);
    animation: sheen-in 1.4s ease-out 2s backwards, sheen-box 24s ease-in-out infinite alternate;
}
.bg-sheen > i { left: 35vmax; top: 35vmax; filter: brightness(3.2) contrast(1.15); transform: translate3d(-74vw, -18vh, 0); animation: sheen-weave 24s ease-in-out infinite alternate; }
/* the light itself is aqua-tinted, like the app's accent */
.bg-sheen::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 255, 255, 0.16), rgba(25, 230, 234, 0.14) 40%, transparent 80%); }
@keyframes sheen-in { from { opacity: 0; } }
@keyframes sheen-box {
    0% { transform: translate3d(78vw, 14vh, 0); }
    50% { transform: translate3d(30vw, 36vh, 0); }
    100% { transform: translate3d(62vw, 72vh, 0); }
}
@keyframes sheen-weave {
    0% { transform: translate3d(-78vw, -14vh, 0); }
    50% { transform: translate3d(-30vw, -36vh, 0); }
    100% { transform: translate3d(-62vw, -72vh, 0); }
}
/* Once the pointer moves, site.js owns the transforms (the fade-in keeps running). */
html.sheen-live .bg-sheen { animation: sheen-in 1.4s ease-out 2s backwards; }
html.sheen-live .bg-sheen > i { animation: none; }
/* Touch screens (Marc 2026-10-27): no pointer, so a resting pool just sat on the
   hero text and made it unreadable. There the light only appears under the finger
   (site.js adds html.sheen-touch while a finger is down) and fades when it lifts. */
@media (hover: none) {
    .bg-sheen { animation: none; opacity: 0; transition: opacity .9s ease-out; }
    .bg-sheen > i { animation: none; }
    html.sheen-touch .bg-sheen { opacity: .85; transition: opacity .15s ease-out; }
}

/* ---------- type ---------- */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(h1, h2, h3) { line-height: 1.04; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-title { font-weight: 760; font-stretch: 86%; letter-spacing: -0.018em; line-height: 1; text-wrap: balance; }
/* A static glow behind the title: a drop-shadow filter would re-blur the animated glint every frame. */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-title { position: relative; isolation: isolate; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-title::before { content: ""; position: absolute; inset: -12% -6%; z-index: -1; pointer-events: none; background: radial-gradient(closest-side, var(--c-glow-cyan), transparent); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-eyebrow { font-weight: 500; letter-spacing: .18em; font-size: .78rem; color: var(--c-blue); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .section-title { font-weight: 730; font-stretch: 88%; letter-spacing: -0.012em; text-wrap: balance; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.panel-title, .legal-title, .price-amount, .pay-total, .int-rate-num) { font-weight: 740; font-stretch: 88%; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .card-title { font-weight: 700; font-stretch: 92%; letter-spacing: -0.005em; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .compat-row li { font-weight: 700; font-stretch: 86%; letter-spacing: -0.01em; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .card-num { font-weight: 500; color: var(--c-blue); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .gradient-text { animation-duration: 5s; }
/* copy over the lit weave keeps a soft dark halo so the sheen never eats it */
html[data-site-theme="carbon"] :is(.hero-sub, .hero-note, .section-sub, .section-foot, .compat-note, .pricing-foot) { text-shadow: 0 1px 2px #000, 0 0 14px rgba(0, 0, 0, 0.85); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-note { font-family: var(--font-mono); font-size: .84rem; letter-spacing: .02em; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) ::selection { background: var(--c-glow-blue); color: var(--c-text); }

/* Keyboard focus ring; never on headings: Blazor focuses the page <h1> after each
   navigation (FocusOnNavigate) and a ring there drew a border around the hero title. */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :focus-visible:not(h1, h2, h3, [tabindex="-1"]) { outline: 2px solid var(--c-aqua); outline-offset: 3px; }
:is(h1, h2, h3, [tabindex="-1"]):focus { outline: none; }

/* Hero text is never selectable (every theme, every hero): a selection on the
   gradient-clipped title painted a pale box around the letters. */
:is(.hero, .pa-hero, .hero-title, .hero-eyebrow, .gradient-text) { -webkit-user-select: none; -moz-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }

/* ---------- header ---------- */
/* The bar stays a solid band while the page scrolls under it (Marc 2026-10-27). */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .site-header {
    background: color-mix(in srgb, var(--c-bg) 94%, transparent);
    border-bottom-color: var(--c-border-strong);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
html[data-site-theme="clear"] .site-header { box-shadow: 0 6px 18px rgba(10, 42, 48, 0.1); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .brand-logo { height: 40px; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .site-lang-menu { background: var(--c-bg-raise); }

/* ---------- keys (buttons): the app's moulded keys ---------- */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn {
    font-family: var(--font-body); font-weight: 700; border-radius: var(--radius-key);
    border: 1px solid var(--c-border-strong);
    background: var(--key-bg), var(--key-base); color: var(--c-text);
    box-shadow: var(--pane-hilite), var(--key-shadow);
}
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn:hover { transform: translateY(-1px); filter: brightness(1.1); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn:active { transform: translateY(1px) scale(.985); filter: brightness(.96); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn-primary {
    background: var(--lit-bg); color: var(--c-on-aqua);
    border-color: color-mix(in srgb, var(--c-aqua) 60%, white); box-shadow: var(--lit-glow);
}
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn-wallet { background: var(--c-wallet-bg); color: var(--c-wallet-fg); border-color: var(--c-wallet-bg); box-shadow: var(--key-shadow); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .btn-bizum { background: var(--c-bizum-bg); color: var(--c-bizum-fg); border-color: var(--c-bizum-bg); box-shadow: var(--key-shadow); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .nav-burger { border-radius: var(--radius-key); background: var(--key-bg), var(--key-base); box-shadow: var(--pane-hilite); }

/* Two-way switches: the chosen side is the lit key. */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.billing-toggle, .plan-toggle) { border-radius: 14px; background: var(--c-well); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.billing-toggle label, .plan-toggle button) { border-radius: 10px; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) #bill-mo:checked ~ .billing-toggle label[for="bill-mo"],
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) #bill-yr:checked ~ .billing-toggle label[for="bill-yr"],
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .plan-toggle button.on { background: var(--lit-bg); color: var(--c-on-aqua); box-shadow: var(--lit-glow); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) #bill-mo:checked ~ .billing-toggle label[for="bill-mo"] .save-badge,
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) #bill-yr:checked ~ .billing-toggle label[for="bill-yr"] .save-badge,
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .plan-toggle button.on .save-badge { background: rgba(0, 0, 0, 0.14); color: var(--c-on-aqua); }

/* ---------- panes: cards, price cards, panels (the hard gloss line at 42 %) ---------- */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.card, .price-card, .panel-card, .int-rate) {
    background: var(--gloss) top / 100% var(--gloss-cap) no-repeat, var(--c-pane);
    border: 1px solid var(--c-border-strong);
    box-shadow: var(--pane-hilite), var(--shadow-card);
    backdrop-filter: none; -webkit-backdrop-filter: none;
}
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .card:hover { background: var(--gloss) top / 100% var(--gloss-cap) no-repeat, var(--c-pane); border-color: color-mix(in srgb, var(--c-aqua) 45%, transparent); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .card-img-wrap { border-radius: 12px; box-shadow: inset 0 0 0 1px var(--c-border); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.card, .price-card):hover::after { opacity: .35; }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .price-card:hover { box-shadow: var(--pane-hilite), 0 0 0 1px var(--c-glow-blue), var(--shadow-card); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .price-card.featured { border-color: color-mix(in srgb, var(--c-aqua) 70%, transparent); animation-name: featured-breathe-lit; }
@keyframes featured-breathe-lit {
    0%, 100% { box-shadow: var(--pane-hilite), 0 0 0 1px var(--c-glow-blue), 0 0 24px var(--c-glow-blue); }
    50% { box-shadow: var(--pane-hilite), 0 0 0 1px var(--c-glow-cyan), 0 0 46px var(--c-glow-blue); }
}
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .price-badge { background: var(--lit-bg); color: var(--c-on-aqua); border-radius: 8px; font-weight: 600; box-shadow: 0 0 12px var(--c-glow-cyan); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .price-list li::before { color: var(--c-blue); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) :is(.cart-line, .acct-row, .mod-row, .pay-method, .cancel-summary) { background: var(--c-surface-2); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .field :is(input, select, textarea):focus { border-color: var(--c-aqua); box-shadow: 0 0 0 3px var(--c-glow-cyan); }

/* ---------- hero: the photo is a lit screen; its status line powers on ---------- */
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-img-wrap {
    border: 1px solid var(--c-border-strong);
    box-shadow: var(--pane-hilite), var(--shadow-card);
}
html[data-site-theme="carbon"] .hero-img-wrap { box-shadow: var(--pane-hilite), var(--shadow-card), 0 0 0 1px rgba(0, 0, 0, 0.4); }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-img-wrap::after {
    content: ""; position: absolute; left: 18%; right: 18%; bottom: 0; height: 2px; border-radius: 2px;
    background: var(--c-aqua);
    box-shadow: 0 0 10px var(--c-aqua), 0 0 26px var(--c-glow-blue);
    transform-origin: center; animation: status-on 1.1s var(--ease-out) 1.55s backwards;
}
@keyframes status-on { from { transform: scaleX(0); opacity: 0; } 30% { opacity: 1; } to { transform: scaleX(1); opacity: 1; } }
html:is([data-site-theme="carbon"], [data-site-theme="clear"]) .hero-img-glow { background: radial-gradient(50% 50% at 50% 60%, var(--c-glow-cyan), transparent 70%); }

/* ---------- CLEAR: the dark-palette literals of the base sheet ---------- */
html[data-site-theme="clear"] .form-msg.err { color: #b3202f; }
html[data-site-theme="clear"] .form-msg.ok { color: #13744d; }
html[data-site-theme="clear"] .form-msg.warn { color: #8a4f06; }
html[data-site-theme="clear"] .save-badge { color: #13744d; }
html[data-site-theme="clear"] .spinner { border-color: rgba(10, 42, 48, 0.2); border-top-color: var(--c-blue); }
html[data-site-theme="clear"] .theme-dot.active { border-color: var(--c-text); }

/* ---------- theme picker dots ---------- */
.theme-dot.carbon { background: linear-gradient(135deg, #0c0f10 55%, #19e6ea 55%); }
.theme-dot.clear { background: linear-gradient(135deg, #ffffff 55%, #19d3d8 55%); box-shadow: inset 0 0 0 1px rgba(10, 42, 48, 0.2); }

@media (prefers-reduced-motion: reduce) {
    .bg-sweep, .bg-flash { display: none !important; }
    .bg-sheen, .bg-sheen > i { animation: none !important; }
}
