/*
 * Operakliniken Hub - Design tokens + layout primitives
 *
 * Brand: Operakliniken brun accent confirmed from existing footer-injection
 * in workers/site-router/src/renderer.js line 126.
 *
 * Approach: mobile-first, system fonts with Inter fallback, accessible
 * color contrasts WCAG AA, no third-party font CDN dependencies for v1.
 */

:root {
    /* Brand colors.
     *
     * These were cornflower blue (#5176cd / #264698) - a leftover from the
     * generic template that contradicted this file's own header note above
     * ("Brand: Operakliniken brun accent") and every other --op-* token in
     * this block, all of which are warm. It painted every primary CTA on the
     * treatment pages cold blue on a cream and brown site, and gave white
     * button text only 4.35:1, below the WCAG AA target this file claims.
     *
     * The palette injected per site (getPaletteCSS) is the truth; the hex
     * values are the Operakliniken fallback for a page rendered without it.
     */
    --op-accent: var(--accent-dark, #6e5440);        /* fills, white text 6.99:1 */
    --op-accent-strong: #4a3a30;                     /* hover + emphasis, 10.8:1 */
    --op-accent-soft: rgba(110, 84, 64, 0.12);
    --op-accent-ring: rgba(110, 84, 64, 0.32);
    /* Accent for dark surfaces, where the fill accent is too dark to read. */
    --op-accent-on-dark: var(--accent, #b08d6e);     /* on --op-bg-strong 6.2:1 */

    /* Surface */
    --op-bg-canvas: #fcf9f4;
    --op-bg-surface: #ffffff;
    --op-bg-muted: #f5efe6;
    --op-bg-strong: #1a0f0a;

    /* Text */
    --op-text-primary: #1a0f0a;
    --op-text-secondary: #4a3a30;
    --op-text-muted: #7f6a5d;
    --op-text-on-accent: #ffffff;
    --op-text-on-dark: #fcf9f4;

    /* Borders */
    --op-border: #e7dccd;
    --op-border-strong: #c8b8a2;
    --op-border-focus: var(--op-accent);

    /* Status */
    --op-ok: #2d7a4f;
    --op-warn: #b86b00;
    --op-err: #a3261a;

    /* Typography */
    --op-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --op-font-display: 'Space Grotesk', var(--op-font-sans);
    --op-font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

    --op-text-xs: 0.75rem;
    --op-text-sm: 0.875rem;
    --op-text-base: 1rem;
    --op-text-lg: 1.125rem;
    --op-text-xl: 1.25rem;
    --op-text-2xl: 1.5rem;
    --op-text-3xl: 1.875rem;
    --op-text-4xl: 2.25rem;
    --op-text-5xl: 3rem;

    --op-leading-tight: 1.2;
    --op-leading-snug: 1.35;
    --op-leading-normal: 1.55;
    --op-leading-relaxed: 1.7;

    /* Spacing */
    --op-space-1: 0.25rem;
    --op-space-2: 0.5rem;
    --op-space-3: 0.75rem;
    --op-space-4: 1rem;
    --op-space-5: 1.5rem;
    --op-space-6: 2rem;
    --op-space-7: 2.5rem;
    --op-space-8: 3rem;
    --op-space-10: 4rem;
    --op-space-12: 5rem;
    --op-space-16: 7rem;

    /* Radii */
    --op-radius-sm: 4px;
    --op-radius-md: 8px;
    --op-radius-lg: 16px;
    --op-radius-pill: 999px;

    /* Shadows */
    --op-shadow-soft: 0 1px 2px rgba(26, 15, 10, 0.06), 0 1px 3px rgba(26, 15, 10, 0.04);
    --op-shadow-card: 0 4px 16px rgba(26, 15, 10, 0.06);
    --op-shadow-pop: 0 12px 32px rgba(26, 15, 10, 0.10);

    /* Layout */
    --op-max-w-content: 65ch;
    --op-max-w-page: 1180px;
    --op-max-w-wide: 1400px;

    /* Motion */
    --op-motion-fast: 120ms ease-out;
    --op-motion-base: 220ms cubic-bezier(0.2, 0.6, 0.2, 1);
    --op-motion-slow: 420ms cubic-bezier(0.2, 0.6, 0.2, 1);

    /* Focus ring */
    --op-focus-ring: 0 0 0 3px var(--op-accent-ring);

    /* App shell (docs/rules/mobile-app-shell-standard.md): the compact
       app composition is token-driven - bar heights, flow-screen padding
       and the minimum touch target live here so the shell recipe never
       hardcodes them. */
    --op-appbar-h: 56px;
    --op-flowbar-h: 56px;
    --op-flow-pad: 12px;
    --op-touch-min: 44px;
}

/* Mobile section rhythm: the big block-spacing tokens compress on narrow
   viewports so pages keep a mobile-adapted rhythm instead of desktop-scale
   dead bands (the /ordlista hero gap at 375px was 112px + 112px + 64px).
   Component-scale tokens (space-1..8) stay fixed. Breakpoint matches the
   shared MOBILE_MAX in workers/site-router/src/templates/breakpoints.js.
   CC217 survivor under docs/rules/mobile-app-shell-standard.md: the flip
   happens on :root and the consuming elements (.op-section, .op-footer)
   ARE the band containers - an element cannot query its own size, and no
   ancestor may be a container while fixed-position overlays render inside
   <main> (container-type re-anchors fixed descendants). Converting this
   needs a markup-owned shell wrapper; see the CC217 report. */
@media (max-width: 719.98px) {
    :root {
        --op-space-10: 3rem;
        --op-space-12: 3.5rem;
        --op-space-16: 4rem;
    }
}

/* Reset baseline (scoped to .op-hub root so existing site-router pages are not affected) */
.op-hub *,
.op-hub *::before,
.op-hub *::after {
    box-sizing: border-box;
}

.op-hub {
    margin: 0;
    background: var(--op-bg-canvas);
    color: var(--op-text-primary);
    font-family: var(--op-font-sans);
    font-size: var(--op-text-base);
    line-height: var(--op-leading-normal);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.op-hub h1, .op-hub h2, .op-hub h3, .op-hub h4 {
    font-family: var(--op-font-display);
    color: var(--op-text-primary);
    line-height: var(--op-leading-tight);
    margin: 0 0 var(--op-space-4) 0;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.op-hub h1 { font-size: var(--op-text-4xl); }
.op-hub h2 { font-size: var(--op-text-3xl); }
.op-hub h3 { font-size: var(--op-text-2xl); }
.op-hub h4 { font-size: var(--op-text-xl); }

.op-hub p { margin: 0 0 var(--op-space-4) 0; max-width: var(--op-max-w-content); }
/* Body-copy links only. A CTA is usually an <a class="op-btn ...">, and
   `.op-hub a` (one class + one type) outranks a single-class component rule
   like `.op-btn--primary` or `.op-booking__consult`, so buttons used to take
   the body link color, its underline and its focus ring instead of their own.
   That painted the primary CTA label in the accent color on the accent fill
   and the consultation link in dark brown on the near-black booking band.
   Excluding .op-btn hands every button back its own contract. */
/* :where() so the exclusion costs NOTHING in specificity. Plain :not(.op-btn)
   raises this rule to (0,2,1), which then outranks every component rule of the
   form `.component a` (0,1,1) that had been winning on source order - live that
   underlined the price-table booking pills, the treatment TOC and the booking
   card links, and gave the pills a 2.68:1 hover. :where(.op-btn) contributes 0,
   so the rule stays (0,1,1) exactly as before while still skipping buttons. */
.op-hub a:not(:where(.op-btn)) { color: var(--op-accent-strong); text-decoration: underline; text-underline-offset: 3px; }
.op-hub a:not(:where(.op-btn)):hover { color: var(--op-text-primary); }
.op-hub a:not(:where(.op-btn)):focus-visible { outline: none; box-shadow: var(--op-focus-ring); border-radius: var(--op-radius-sm); }

/* Container */
.op-container { max-width: var(--op-max-w-page); margin-inline: auto; padding-inline: var(--op-space-5); }
.op-container--wide { max-width: var(--op-max-w-wide); }
.op-container--narrow { max-width: var(--op-max-w-content); }

/* Container-first responsive (docs/rules/mobile-app-shell-standard.md):
   components adapt to the space around them, so the hub declares two
   query targets - the full-bleed band (.op-section, .op-body3d ->
   op-band) and the page-width column (.op-container -> op-page). The
   @container conditions below use either the standard's canon numbers
   (compact <= 520px, wide > 900px) or this file's historic viewport
   breakpoints translated into container space (720px viewport - 48px
   .op-container padding-inline = 672px; 1080px - 48px = 1032px) so the
   shipped cozy/wide composition does not move. <main class="op-hub">
   itself must NOT become a container: container-type creates a new
   containing block for fixed-position descendants, and pages composed
   from the DB can mount fixed overlays (custom/booking-wizard, hero
   dialogs) inside <main>; band-level containers carry no such risk
   (verified: no position:fixed renders inside .op-section, .op-body3d
   or .op-container in workers/site-router/src). */
.op-section,
.op-body3d { container-type: inline-size; container-name: op-band; }
.op-container { container-type: inline-size; container-name: op-page; }

/* Section spacing */
.op-section { padding-block: var(--op-space-10); }
.op-section--tight { padding-block: var(--op-space-6); }
.op-section--airy { padding-block: var(--op-space-16); }
.op-section--strong { background: var(--op-bg-strong); color: var(--op-text-on-dark); }
.op-section--muted { background: var(--op-bg-muted); }

/* Button */
.op-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--op-space-2);
    padding: var(--op-space-3) var(--op-space-5);
    border-radius: var(--op-radius-pill);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: var(--op-text-base);
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--op-motion-fast), color var(--op-motion-fast), border-color var(--op-motion-fast), box-shadow var(--op-motion-fast);
}
.op-btn:focus-visible { outline: none; box-shadow: var(--op-focus-ring); }
.op-btn--primary { background: var(--op-accent); color: var(--op-text-on-accent); }
.op-btn--primary:hover { background: var(--op-accent-strong); color: var(--op-text-on-accent); }
.op-btn--ghost { background: transparent; color: var(--op-text-primary); border-color: var(--op-border-strong); }
.op-btn--ghost:hover { background: var(--op-bg-muted); }

/* Chip (for claim-chips) */
.op-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--op-space-2);
    padding: var(--op-space-2) var(--op-space-3);
    border-radius: var(--op-radius-pill);
    background: var(--op-bg-surface);
    border: 1px solid var(--op-border);
    font-size: var(--op-text-sm);
    line-height: 1.2;
    color: var(--op-text-secondary);
}
.op-chip--accent { border-color: var(--op-accent); color: var(--op-accent-strong); background: var(--op-accent-soft); }
.op-chip--ok { border-color: rgba(45, 122, 79, 0.4); color: var(--op-ok); background: rgba(45, 122, 79, 0.08); }
.op-chip__icon { width: 14px; height: 14px; flex: 0 0 14px; }

/* Card */
.op-card {
    background: var(--op-bg-surface);
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    padding: var(--op-space-6);
    box-shadow: var(--op-shadow-soft);
    transition: box-shadow var(--op-motion-fast), transform var(--op-motion-fast);
}
.op-card:hover { box-shadow: var(--op-shadow-card); }

/* Grid primitives */
.op-grid { display: grid; gap: var(--op-space-5); }
.op-grid--2 { grid-template-columns: 1fr; }
.op-grid--3 { grid-template-columns: 1fr; }
.op-grid--4 { grid-template-columns: 1fr; }

/* 672px/1032px = the historic 720px/1080px viewport thresholds minus the
   48px .op-container padding-inline (see the container comment above). */
@container op-page (width >= 672px) {
    .op-grid--2 { grid-template-columns: repeat(2, 1fr); }
    .op-grid--3 { grid-template-columns: repeat(2, 1fr); }
    .op-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@container op-page (width >= 1032px) {
    .op-grid--3 { grid-template-columns: repeat(3, 1fr); }
    .op-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

/* Body-nav (used by phase B1) */
.op-body-nav {
    position: relative;
    display: grid;
    gap: var(--op-space-5);
    grid-template-columns: 1fr;
    align-items: start;
    margin-block: var(--op-space-8);
}
/* 880px kept as-is: the surface's own cozy/wide split for this module
   (band width tracks the old viewport threshold on a full-bleed band). */
@container op-band (width >= 880px) {
    .op-body-nav { grid-template-columns: 360px 1fr; }
}
.op-body-nav__svg { display: block; max-width: 360px; width: 100%; height: auto; }
.op-body-nav__svg .op-region {
    fill: var(--op-bg-surface);
    stroke: var(--op-border-strong);
    stroke-width: 1.5;
    cursor: pointer;
    transition: fill var(--op-motion-fast);
}
.op-body-nav__svg .op-region:hover,
.op-body-nav__svg a:hover .op-region,
.op-body-nav__svg a:focus-visible .op-region {
    fill: var(--op-accent-soft);
    stroke: var(--op-accent);
}
.op-body-nav__svg a:focus-visible { outline: none; }
.op-body-nav__svg a:focus-visible .op-region {
    stroke: var(--op-accent);
    stroke-width: 3;
    filter: drop-shadow(0 0 0 3px var(--op-accent-ring));
}
.op-body-nav__quicklinks h3 { font-size: var(--op-text-lg); margin-bottom: var(--op-space-3); }
.op-body-nav__quicklinks ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--op-space-2); }
.op-body-nav__quicklinks a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--op-space-3) var(--op-space-4);
    background: var(--op-bg-surface);
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-md);
    color: var(--op-text-primary);
    text-decoration: none;
    transition: border-color var(--op-motion-fast), background var(--op-motion-fast);
}
.op-body-nav__quicklinks a:hover { border-color: var(--op-accent); background: var(--op-accent-soft); }

/* Stats row / trust row */
.op-trust-row {
    display: grid;
    gap: var(--op-space-5);
    grid-template-columns: 1fr;
}
@container op-page (width >= 672px) { .op-trust-row { grid-template-columns: repeat(3, 1fr); } }
.op-trust-row__item { text-align: center; padding: var(--op-space-5); }
.op-trust-row__item strong { display: block; font-family: var(--op-font-display); font-size: var(--op-text-3xl); color: var(--op-accent); margin-bottom: var(--op-space-2); }
.op-trust-row__item span { color: var(--op-text-secondary); font-size: var(--op-text-sm); }

/* Treatment sections */
.op-treatment-hero { padding-block: var(--op-space-10); border-bottom: 1px solid var(--op-border); }
.op-treatment-hero__meta { display: flex; flex-wrap: wrap; gap: var(--op-space-2); margin-top: var(--op-space-4); }
.op-treatment-toc {
    position: sticky;
    top: var(--op-space-5);
    padding: var(--op-space-5);
    background: var(--op-bg-surface);
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-md);
    font-size: var(--op-text-sm);
}
.op-treatment-toc ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--op-space-2); }
.op-treatment-toc a { color: var(--op-text-secondary); text-decoration: none; display: block; padding: var(--op-space-1) 0; }
.op-treatment-toc a:hover { color: var(--op-accent-strong); }

.op-safety-block {
    background: var(--op-bg-muted);
    border-left: 4px solid var(--op-accent);
    padding: var(--op-space-6);
    border-radius: 0 var(--op-radius-md) var(--op-radius-md) 0;
    margin-block: var(--op-space-6);
}
.op-safety-block h3 { color: var(--op-accent-strong); margin-top: 0; }

/* FAQ accordion */
.op-faq details {
    border-bottom: 1px solid var(--op-border);
    padding: var(--op-space-4) 0;
}
.op-faq summary {
    cursor: pointer;
    font-weight: 500;
    font-size: var(--op-text-lg);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--op-space-4);
}
.op-faq summary::-webkit-details-marker { display: none; }
.op-faq summary::after {
    content: '+';
    color: var(--op-accent);
    font-size: var(--op-text-xl);
    transition: transform var(--op-motion-fast);
}
.op-faq details[open] summary::after { content: '-'; }

/* Footer */
.op-footer {
    background: var(--op-bg-strong);
    color: var(--op-text-on-dark);
    padding-block: var(--op-space-10) var(--op-space-6);
    margin-top: var(--op-space-16);
}
.op-footer a { color: var(--op-accent-on-dark); }
.op-footer a:hover { color: var(--op-bg-canvas); }

/* Skip link */
.op-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--op-accent);
    color: var(--op-text-on-accent);
    padding: var(--op-space-3) var(--op-space-5);
    z-index: 1000;
    text-decoration: none;
    border-radius: 0 0 var(--op-radius-md) 0;
}
.op-skip-link:focus { left: 0; }

/* 3D body navigation */
.op-section--body3d-wrap { padding-block: var(--op-space-6); }
.op-body3d { position: relative; }
.op-body3d__title { font-size: var(--op-text-2xl); margin: 0 0 var(--op-space-3); }
.op-body3d__lead { color: var(--op-text-secondary); margin: 0 0 var(--op-space-5); max-width: 56ch; }
.op-body3d__noscript { display: none; }
.op-body3d__noscript-list { list-style: none; padding: 0; display: grid; gap: var(--op-space-2); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.op-body3d__stage {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--op-space-6);
    align-items: start;
}
/* Canon wide threshold (> 900px). The live render also ships the inline
   BODY3D_STYLE copy of this rule at 880px (byte-pinned, body-nav-3d.js)
   which wins the cascade wherever both apply, so the visible behavior is
   unchanged at every width; this copy goes canon instead of mirroring the
   pinned drift. */
@container op-band (width > 900px) {
    .op-body3d__stage { grid-template-columns: minmax(0, 1fr) 280px; }
}
.op-body3d__canvas-wrap {
    position: relative;
    aspect-ratio: 9 / 12;
    max-width: 560px;
    width: 100%;
    margin-inline: auto;
    border-radius: var(--op-radius-lg);
    background:
        radial-gradient(ellipse at 50% 30%, var(--op-accent-soft), transparent 65%),
        linear-gradient(180deg, var(--op-bg, #fcf9f4) 0%, var(--op-bg-alt, #f6efe2) 100%);
    overflow: hidden;
    box-shadow: 0 2px 24px rgba(0,0,0,0.04), inset 0 0 0 1px var(--op-border, #e7dccd);
}
.op-body3d__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    opacity: 0;
    transition: opacity .35s ease;
}
.op-body3d__canvas--ready { opacity: 1; }
.op-body3d__skeleton {
    position: absolute;
    inset: 0;
    background:
        repeating-linear-gradient(
            115deg,
            rgba(176,141,110,0.06) 0px,
            rgba(176,141,110,0.10) 12px,
            rgba(176,141,110,0.04) 24px
        );
    animation: opBody3dShimmer 1.6s ease-in-out infinite;
    pointer-events: none;
    transition: opacity .35s ease;
}
.op-body3d__skeleton--done { opacity: 0; }
.op-body3d__skeleton--failed { opacity: 1; animation: none; background: var(--op-accent-soft); }
@keyframes opBody3dShimmer {
    0%   { background-position: 0 0; }
    100% { background-position: 0 200%; }
}
.op-body3d__hotspots { position: absolute; inset: 0; pointer-events: none; }
.op-body3d__hotspot {
    position: absolute;
    transform: translate(-50%, -50%);
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 4px;
    border-radius: 999px;
    background: rgba(255,255,255,0.86);
    backdrop-filter: blur(6px);
    border: 1px solid var(--op-border, #e7dccd);
    color: var(--op-text-primary);
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    transition: transform .15s ease, box-shadow .2s ease, background .15s ease, border-color .15s ease;
    cursor: pointer;
}
.op-body3d__hotspot:hover,
.op-body3d__hotspot:focus-visible {
    transform: translate(-50%, -50%) scale(1.06);
    background: var(--op-accent);
    color: var(--op-text-on-accent, #ffffff);
    border-color: var(--op-accent);
    box-shadow: 0 6px 18px rgba(176,141,110,0.28);
    outline: none;
}
.op-body3d__hotspot-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--op-accent);
    box-shadow: 0 0 0 3px rgba(255,255,255,0.9), 0 0 0 4px var(--op-accent-ring);
    flex-shrink: 0;
}
.op-body3d__hotspot:hover .op-body3d__hotspot-dot,
.op-body3d__hotspot:focus-visible .op-body3d__hotspot-dot {
    background: #ffffff;
    box-shadow: 0 0 0 3px rgba(0,0,0,0.04);
}
.op-body3d__hotspot-label { white-space: nowrap; }
.op-body3d__quicklinks {
    padding: var(--op-space-4);
    border: 1px solid var(--op-border, #e7dccd);
    border-radius: var(--op-radius-md);
    background: #fff;
}
.op-body3d__quicklinks h3 { font-size: var(--op-text-base); margin: 0 0 var(--op-space-3); }
.op-body3d__quicklinks ul { list-style: none; padding: 0; margin: 0 0 var(--op-space-3); display: flex; flex-direction: column; gap: 8px; }
.op-body3d__quicklinks a { color: var(--op-accent-strong); text-decoration: none; }
.op-body3d__quicklinks a:hover,
.op-body3d__quicklinks a:focus-visible { text-decoration: underline; }
.op-body3d__all a { color: var(--op-text-secondary); font-size: var(--op-text-sm); }

/* Canon compact threshold (<= 520px); the pinned inline 600px copy keeps
   the live hide in the 521-600px band (same cascade note as the stage
   rule above). */
@container op-band (width <= 520px) {
    .op-body3d__hotspot-label {
        display: none;
    }
    .op-body3d__hotspot {
        padding: 4px;
    }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .op-hub *,
    .op-hub *::before,
    .op-hub *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
