/* ============================================
   Abundera QR, Free QR Code Generator
   ============================================ */

/* --- Fonts (self-hosted Inter) --- */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    /* Cache-buster query MUST match the HTML preload URL exactly, or the
       browser treats them as two different resources and logs "preloaded
       but not used", which Google's render service reports as a page-
       resource "Other error" (flagged in GSC 2026-04-23). The deploy
       pipeline substitutes 202607030852 with the build timestamp. */
    src: url('/fonts/inter-latin.woff2?v=202607030852') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/fonts/inter-latin-ext.woff2?v=202607030852') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Inter Fallback';
    src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Arial');
    font-display: swap;
    size-adjust: 100%;
    ascent-override: 90%;
    descent-override: 22%;
    line-gap-override: 0%;
}

/* --- Reset & Base --- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

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

/* Baseline: the HTML `hidden` attribute should ALWAYS hide an element,
   regardless of what display value any component CSS sets. Browsers set
   [hidden]{display:none} without !important, so a component rule like
   `.btn-spinner{display:inline-block}` silently wins and the element stays
   visible. This has bitten us repeatedly. Enforce it once, globally, so
   component CSS never has to think about it. */
[hidden] {
    display: none !important;
}

:root {
    /* color-scheme: dark tells browsers to render native form controls
       (checkboxes, radios, date pickers, scrollbars) in dark theme so
       they're visible on our dark surfaces. Without this, an unchecked
       checkbox is a near-white outline on a dark card, effectively
       invisible until hover. */
    color-scheme: dark;

    /* --- Per-symbology capability gating ---
       Style controls whose engine-declared capability is `false` for
       the currently-selected encoder type get this class via the JS
       _applyCapabilitiesForType helper. E.g. 1D barcodes (Code128,
       EAN, UPC) auto-hide dot-shape, eye-shape, logo, gradient. */
    --cap-hidden: not-used;

    /* --- Surface + text + accent palette -------------------------
       Restored 2026-05-20: prior "DRY hex tokens" pass accidentally
       turned 14 var definitions into self-references (e.g.
       `--blue: var(--blue);`) — broken CSS that browsers silently
       cascade to invalid/initial. Real values recovered from git
       commit 01636ece + the substitution map in the broken commit
       message (da8ae2ef0). */
    --bg: #08090a;
    --surface-1: #0f1012;
    --surface-2: #161719;
    --surface-3: #1e1f22;
    --text: #f5f5f5;
    --text-secondary: #e0e0e0;
    --text-muted: #a3a3a3;
    --border: rgba(255, 255, 255, 0.08);
    --border-hover: rgba(255, 255, 255, 0.15);
    --blue: #60a5fa;
    --purple: #a78bfa;
    --green: #34d399;
    --pink: #fb7185;
    --amber: #f59e0b;
    --yellow: #fbbf24;
    --red: #ef4444;
    --white: #ffffff;
    --black: #000000;
    --surface-tile: #E5E7EB;
    --surface-tile-hover: #F1F5F9;
    --tile-border: #94A3B8;
    --on-tile: #1F2937;
    --radius: 12px;
    --radius-lg: 16px;

    /* --- Spacing scale (Phase 2, 4/8 grid) ---------------------
       Material 3 + Carbon v11 + Tailwind consensus: powers-of-two
       and multiples-of-8 read as a coherent rhythm. Use --space-1
       and --space-2 for inline gaps (icon+label); --space-3 and
       above for stack/block spacing. Always reference these
       tokens, never hard-code a px value for spacing. */
    --space-0: 0;
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-16: 64px;
    --space-20: 80px;
    --space-24: 96px;

    /* --- Motion tokens (Phase 2) --------------------------------
       Material 3 Expressive standard easings + durations. Use
       --motion-emphasized for state changes the user is watching
       (sheets, modals, expansions); --motion-standard for
       supporting transitions (hover, focus); --motion-instant for
       snap-into-place updates (scroll restore, modal close).
       Every transition or animation MUST honor
       prefers-reduced-motion via the @media block at line ~165 , 
       that block resets duration to 0.01ms across the document. */
    --motion-instant: 1ms;
    --motion-fast: 120ms cubic-bezier(0.4, 0, 0.2, 1);
    --motion-standard: 200ms cubic-bezier(0.4, 0, 0.2, 1);
    --motion-emphasized: 300ms cubic-bezier(0.2, 0, 0, 1);
    --motion-decelerated: 250ms cubic-bezier(0, 0, 0.2, 1);
    --motion-accelerated: 200ms cubic-bezier(0.4, 0, 1, 1);
}

/* overflow-x:clip (NOT hidden) on html + body. Clip prevents
   mobile UAs from triggering shrink-to-fit zoom when a wide
   element appears late, AND unlike overflow-x:hidden it does NOT
   create a scroll container — so descendants with position:sticky
   (the desktop QR preview panel) still work. Wide-support since
   Chrome 90 / Safari 16 / Firefox 81. */
html {
    scroll-behavior: smooth;
    overflow-x: clip;
}

body {
    font-family: 'Inter', 'Inter Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    min-height: 100dvh;
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
    width: 100%;
    max-width: 100vw;
}

/* --- Skip Link --- */
.skip-link {
    position: absolute;
    top: -100%;
    inset-inline-start: var(--space-4);
    padding: 8px 16px;
    background: var(--blue);
    color: var(--bg);
    border-radius: 0 0 8px 8px;
    font-size: 0.875rem;
    font-weight: 500;
    text-decoration: none;
    z-index: 100;
    transition: top 0.2s;
}

.skip-link:focus { top: 0; }

/* Screen-reader only, visually hidden but still announced by AT.
   Standard a11y utility for sr-only live regions (e.g. BCD modal
   status, form-error announcements). Uses the "clip trick" so the
   element is still reachable by AT cursor but takes zero visual space. */
.sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --- Focus styles ---
   WCAG 2.2 SC 2.4.11 "Focus Not Obscured (Minimum)" + 2.4.13 "Focus
   Appearance" guidance: focus indicator must be visible without being
   obscured, large enough to see, and high enough contrast. 3px outline
   with a 2px offset plus a box-shadow halo so the ring is legible on
   any background (dark surface, coloured button, image). */
:focus-visible {
    outline: 3px solid var(--blue);
    outline-offset: 2px;
    box-shadow: 0 0 0 1px var(--bg);
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 3px solid var(--blue);
    outline-offset: 1px;
    border-color: var(--blue);
    box-shadow: 0 0 0 1px var(--bg), 0 0 0 5px rgba(96, 165, 250, 0.25);
}

/* WCAG forced-colors support (Windows High Contrast Mode, macOS
   Increase Contrast). Defer to system colours so the focus ring is
   visible even when user CSS overrides our palette. */
@media (forced-colors: active) {
    :focus-visible {
        outline-color: Highlight;
    }
    .btn, button, input, textarea, select, a {
        forced-color-adjust: auto;
    }
}

/* WCAG 2.3.3 Animation from Interactions (AAA) + 2.2.2 Pause, Stop,
   Hide: suppress decorative animation for users who ask for it. Keeps
   functional transitions (<=80ms nudges, focus rings) but kills the
   long ambient ones (orb float, fade-in hero). */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* --- Background Orbs --- */
.bg-orbs {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
}

.orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(120px);
    opacity: 0.12;
}

.orb-1 {
    width: 600px;
    height: 600px;
    background: var(--blue);
    top: -200px;
    inset-inline-end: -100px;
    animation: float1 25s ease-in-out infinite;
}

.orb-2 {
    width: 500px;
    height: 500px;
    background: var(--purple);
    bottom: -150px;
    inset-inline-start: -100px;
    animation: float2 30s ease-in-out infinite;
}

.orb-3 {
    width: 400px;
    height: 400px;
    background: var(--green);
    top: 50%;
    inset-inline-start: 50%;
    transform: translate(-50%, -50%);
    animation: float3 20s ease-in-out infinite;
}

@keyframes float1 { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-80px, 60px); } }
@keyframes float2 { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(60px, -80px); } }
@keyframes float3 { 0%, 100% { transform: translate(-50%, -50%); } 50% { transform: translate(-40%, -60%); } }

/* --- Layout --- */
/* site-header intentionally excluded: giving it a stacking context via z-index
   traps the fixed .header-nav drawer below body-level overlays on mobile,
   making hamburger menu items unclickable. See mobile nav comment below. */
main, .site-footer {
    position: relative;
    z-index: 1;
}
.site-header {
    position: relative;
}

main {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 24px;
}

/* --- Header --- */
.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px;
    max-width: 960px;
    margin: 0 auto;
}

.logo {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: var(--text);
    font-size: 1.1rem;
    font-weight: 500;
}

.logo strong { font-weight: 700; }
.logo-shortdomain { color: var(--text-muted, var(--text-muted)); font-weight: 400; font-size: 0.85em; margin-inline-start: 2px; }
@media (max-width: 480px) { .logo-shortdomain { display: none; } }

.header-nav {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.nav-hamburger {
    display: none;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
    padding: var(--space-2);
    border-radius: var(--radius);
    cursor: pointer;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s;
    position: relative;
    z-index: 1600;
}
/* Make sure the SVG inside the hamburger never becomes the click target , 
   that was occasionally swallowing the click on browsers where event.target
   is the inner <line> element and bubbling was being interfered with. */
.nav-hamburger svg { pointer-events: none; }

.nav-hamburger:hover {
    background: var(--surface-2);
    border-color: var(--border-hover);
}
.nav-hamburger:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

.nav-link {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.875rem;
    padding: 6px 12px;
    border-radius: 8px;
    transition: color 0.2s, background 0.2s;
}

.nav-link:hover {
    color: var(--text);
    background: var(--surface-2);
}

.sign-link {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--blue);
}

.sign-link:hover {
    color: var(--text);
    background: rgba(96, 165, 250, 0.1);
}

.nav-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
    font-size: 0.875rem;
    padding: 6px 12px;
    border-radius: 8px;
    border: 1px solid var(--border-hover);
    background: transparent;
    font-family: inherit;
    cursor: pointer;
    transition: color 0.2s, background 0.2s, border-color 0.2s;
}

.nav-btn:hover {
    color: var(--text);
    background: var(--surface-2);
    border-color: var(--text-muted);
}

#btn-install {
    color: var(--green);
    border-color: rgba(52, 211, 153, 0.4);
}

#btn-install:hover {
    background: rgba(52, 211, 153, 0.1);
    border-color: var(--green);
    color: var(--green);
}

/* --- Hero --- */
.hero {
    text-align: center;
    padding: 48px 0 32px;
}

.hero-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px 14px 6px 12px;
    margin-bottom: 18px;
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.12), rgba(167, 139, 250, 0.12));
    border: 1px solid var(--border-hover);
    border-radius: 999px;
    color: var(--text);
    font-size: 0.8125rem;
    font-weight: 500;
    text-decoration: none;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}

.hero-pill:hover {
    border-color: var(--blue);
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.2), rgba(167, 139, 250, 0.2));
    transform: translateY(-1px);
}

.hero-pill-spark {
    font-size: 0.875rem;
    line-height: 1;
}

.hero-pill-arrow {
    color: var(--blue);
    font-weight: 600;
    transition: transform 0.15s;
}

.hero-pill:hover .hero-pill-arrow {
    transform: translateX(2px);
}

.hero h1 {
    font-size: clamp(1.75rem, 4.5vw, 2.75rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    background: linear-gradient(135deg, var(--text), var(--blue));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.hero-subtitle {
    color: var(--text-muted);
    font-size: 1.125rem;
    margin-top: var(--space-3);
}

.hero-refrain {
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    margin-top: 10px;
    margin-bottom: 0;
}

.hero-features {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: center;
    margin: 18px auto 0;
    padding: 0;
    list-style: none;
    max-width: 720px;
}

.hero-features li {
    padding: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.8125rem;
    color: var(--text-muted);
    transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.15s;
}

/* Every hero feature is now a real link. The chip styling lives on <li>,
   the anchor inherits and adds hover + focus affordance. */
.hero-features .hero-feat-link {
    display: inline-block;
    padding: 6px 12px;
    color: inherit;
    text-decoration: none;
    border-radius: inherit;
    transition: color 0.15s;
}
.hero-features li:hover {
    border-color: var(--accent, var(--blue));
    background: rgba(96, 165, 250, 0.08);
    color: var(--text, var(--text));
    transform: translateY(-1px);
}
.hero-features .hero-feat-link:focus-visible {
    outline: 2px solid var(--accent, var(--blue));
    outline-offset: 3px;
}

.hero-features li.featured {
    background: linear-gradient(135deg, var(--blue), var(--purple));
    color: var(--bg);
    border-color: transparent;
    font-weight: 600;
    box-shadow: 0 2px 12px rgba(96, 165, 250, 0.3);
}

.hero-features li.featured:hover {
    transform: translateY(-1px);
    background: linear-gradient(135deg, var(--blue), var(--purple));
    box-shadow: 0 4px 16px rgba(96, 165, 250, 0.45);
}
.hero-features li.featured .hero-feat-link { color: var(--bg); }

/* R3: Trust strip, verify-me links. Quieter than hero-features so it
   reads as substantiation, not marketing. Sits below hero-features and
   above the Pro CTA card. */
.trust-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 10px;
    justify-content: center;
    align-items: center;
    margin: 14px auto 0;
    padding: 0;
    list-style: none;
    max-width: 820px;
    font-size: 0.78rem;
}
.trust-strip li {
    display: inline-flex;
    align-items: center;
}
.trust-strip a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border-radius: 999px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.trust-strip a:hover {
    color: var(--text);
    border-color: var(--border);
    background: var(--surface-2);
}
.trust-strip .trust-ico {
    font-size: 0.85rem;
    line-height: 1;
    opacity: 0.8;
}
@media (max-width: 640px) {
  .trust-strip { font-size: 0.72rem; gap: 4px 6px; }
  .trust-strip a { padding: 3px 8px; }
}

/* V1: Verify panel, collapsible block under the trust strip that shows
   real-time privacy metrics computed in the browser. */
.verify-panel {
    max-width: 820px;
    margin: 10px auto 0;
    padding: 0;
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 12px;
    background: var(--surface-2, var(--surface-2));
    overflow: hidden;
}
.verify-panel[open] { background: var(--surface-1, #111214); }
.verify-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text-muted, #b0b0b0);
    user-select: none;
    list-style: none;
}
.verify-summary::-webkit-details-marker { display: none; }
.verify-summary:hover { color: var(--text, var(--text)); }
.verify-panel[open] .verify-summary { color: var(--text, var(--text)); }
.verify-pulse {
    width: 8px; height: 8px; border-radius: 50%;
    background: rgb(34, 197, 94);
    flex-shrink: 0;
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.6);
    animation: verify-pulse 2.4s ease-in-out infinite;
}
@keyframes verify-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.55); }
  70%  { box-shadow: 0 0 0 10px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .verify-pulse { animation: none; }
}
.verify-label { flex: 1 1 auto; }
.verify-chev {
    transition: transform 0.18s ease;
    font-size: 0.9rem;
    opacity: 0.6;
}
.verify-panel[open] .verify-chev { transform: rotate(180deg); }
.verify-body {
    padding: 4px 16px 16px;
    border-top: 1px solid var(--border, #2a2a2d);
}
.verify-lead {
    font-size: 0.8rem;
    color: var(--text-muted, #888);
    margin: 12px 0 14px;
    line-height: 1.5;
}
.verify-metrics {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-2);
}
@media (max-width: 640px) {
  .verify-metrics { grid-template-columns: 1fr; }
}
.verify-metric {
    padding: 10px 12px;
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 8px;
    background: var(--surface-2, var(--surface-2));
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto auto;
    gap: 2px 10px;
    font-size: 0.78rem;
}
.verify-metric-label {
    grid-column: 1;
    grid-row: 1;
    color: var(--text, var(--text));
    font-weight: 500;
}
.verify-metric-value {
    grid-column: 2;
    grid-row: 1;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 6px;
    background: rgba(100, 116, 139, 0.15);
    color: var(--text-muted, #aaa);
    white-space: nowrap;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.verify-metric-value.verify-ok {
    background: rgba(34, 197, 94, 0.14);
    color: rgb(134, 239, 172);
}
.verify-metric-value.verify-warn {
    background: rgba(250, 204, 21, 0.16);
    color: rgb(254, 240, 138);
}
.verify-metric-expect {
    grid-column: 1 / -1;
    grid-row: 2;
    font-size: 0.72rem;
    color: var(--text-muted, #888);
    opacity: 0.85;
}
.verify-metric-why {
    grid-column: 1 / -1;
    grid-row: 3;
    font-size: 0.72rem;
    color: var(--text-muted, #888);
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    transition: opacity 0.15s, max-height 0.15s;
}
.verify-metric:hover .verify-metric-why,
.verify-metric:focus-within .verify-metric-why {
    opacity: 1;
    max-height: 120px;
    margin-top: 2px;
}
.verify-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    margin-top: 14px;
    font-size: 0.78rem;
}
.verify-refresh {
    padding: 6px 12px;
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 7px;
    background: transparent;
    color: var(--text, var(--text));
    cursor: pointer;
    font-size: 0.78rem;
    font-weight: 500;
    transition: border-color 0.15s, background 0.15s;
}
.verify-refresh:hover {
    border-color: var(--accent, var(--blue));
    background: rgba(96, 165, 250, 0.08);
}
.verify-manifesto {
    color: var(--accent, var(--blue));
    text-decoration: none;
    margin-inline-start: auto;
}
.verify-manifesto:hover { text-decoration: underline; }
@media (max-width: 480px) {
  .verify-summary { font-size: 0.78rem; padding: 10px 12px; }
  .verify-body { padding: 4px 12px 14px; }
  .verify-manifesto { margin-inline-start: 0; }
}

/* Pro CTA coming-soon card.
   Width matches the Sign CTA it sits alongside on /index.html , 
   both fill the main container (max-width 960px minus 24px padding
   on each side). The earlier 760px cap made Pro read as visually
   "smaller than Sign" when they were adjacent, which is the opposite
   of the intended hierarchy (both are full products). */
.pro-cta-card {
    position: relative;
    margin: 32px auto 40px;
    padding: 1px;
    border-radius: 20px;
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.55), rgba(167, 139, 250, 0.55) 50%, rgba(251, 113, 133, 0.4));
    isolation: isolate;
}

.pro-cta-glow {
    position: absolute;
    inset: -40px;
    background: radial-gradient(ellipse at 30% 0%, rgba(96, 165, 250, 0.22), transparent 60%),
                radial-gradient(ellipse at 80% 100%, rgba(167, 139, 250, 0.22), transparent 60%);
    filter: blur(24px);
    z-index: -1;
    pointer-events: none;
    opacity: 0.9;
}

.pro-cta-inner {
    background: linear-gradient(135deg, rgba(15, 16, 18, 0.96), rgba(22, 23, 25, 0.96));
    border-radius: 19px;
    padding: 28px 32px;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
}

.pro-cta-top {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.pro-cta-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 4px 12px;
    width: fit-content;
    background: rgba(96, 165, 250, 0.12);
    border: 1px solid rgba(96, 165, 250, 0.35);
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--blue);
}

.pro-cta-pill-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--blue);
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.25);
    animation: proCtaPulse 2s ease-in-out infinite;
}

@keyframes proCtaPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.55; transform: scale(0.85); }
}

.pro-cta-title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text);
    background: linear-gradient(135deg, var(--text), #c5c9ff);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.pro-cta-sub {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

.pro-cta-features {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.pro-cta-feat {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 8px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text);
}

.pro-cta-feat-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.2), rgba(167, 139, 250, 0.2));
    color: var(--blue);
    flex-shrink: 0;
}

.pro-cta-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px 20px;
    margin-top: var(--space-1);
}

/* Two-column "Free is for / Pro is for" split, reviewer-endorsed
   structure that makes the tier fit obvious without nagging. */
.pro-cta-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
    margin: 8px 0 4px;
}
@media (max-width: 640px) {
  .pro-cta-split { grid-template-columns: 1fr; gap: var(--space-3); }
}
.pro-cta-col {
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.02);
}
.pro-cta-col-pro {
    background: linear-gradient(
        135deg,
        rgba(96, 165, 250, 0.06),
        rgba(167, 139, 250, 0.06)
    );
    border-color: rgba(96, 165, 250, 0.22);
}
.pro-cta-col-title {
    margin: 0 0 8px;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.pro-cta-col-pro .pro-cta-col-title {
    color: var(--blue);
}
.pro-cta-col-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 0.88rem;
    color: var(--text);
}
.pro-cta-col-list li {
    position: relative;
    padding-inline-start: 18px;
}
.pro-cta-col-list li::before {
    content: "✓";
    position: absolute;
    inset-inline-start: 0;
    color: var(--text-muted);
    font-weight: 700;
    font-size: 0.75rem;
    line-height: 1.5;
}
.pro-cta-col-pro .pro-cta-col-list li::before {
    color: var(--blue);
}
.pro-cta-guarantee {
    margin: 12px 0 0;
    padding: 12px 14px;
    border: 1px dashed var(--border);
    border-radius: 10px;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.pro-cta-guarantee a {
    color: var(--accent, var(--blue));
    text-decoration: none;
    border-bottom: 1px dashed currentColor;
    font-weight: 500;
    transition: color 0.15s;
}
.pro-cta-guarantee a:hover {
    color: var(--text, var(--text));
    border-bottom-style: solid;
}

.pro-cta-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 11px 22px;
    background: linear-gradient(135deg, var(--blue), var(--purple));
    color: var(--bg);
    font-weight: 600;
    font-size: 0.95rem;
    text-decoration: none;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(96, 165, 250, 0.28);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.pro-cta-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 20px rgba(96, 165, 250, 0.4);
}

.pro-cta-btn-arrow {
    transition: transform 0.15s ease;
}

.pro-cta-btn:hover .pro-cta-btn-arrow {
    transform: translateX(3px);
}

.pro-cta-link {
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
    border-bottom: 1px dashed var(--border-hover);
    padding-bottom: 1px;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.pro-cta-link:hover {
    color: var(--blue);
    border-bottom-color: var(--blue);
}

@media (max-width: 640px) {
    .pro-cta-card {
        margin: 24px auto 32px;
    }
    .pro-cta-inner {
        padding: 22px 20px;
    }
    .pro-cta-title {
        font-size: 1.15rem;
    }
    .pro-cta-sub {
        font-size: 0.9rem;
    }
    .pro-cta-actions {
        flex-direction: column;
        align-items: stretch;
    }
    .pro-cta-btn {
        justify-content: center;
    }
    .pro-cta-link {
        text-align: center;
    }
}

/* GS1 Sunrise 2027 enhancements */
.gs1-sunrise-banner {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: 10px 14px;
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.4);
    border-radius: var(--radius);
    font-size: 0.8rem;
    color: var(--text);
    margin-bottom: var(--space-1);
}

.gs1-sunrise-banner a {
    color: var(--blue);
    text-decoration: none;
}

.gs1-sunrise-banner a:hover {
    text-decoration: underline;
}

.input-with-status {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.input-with-status input {
    flex: 1;
}

.gtin-status {
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    min-width: 60px;
    text-align: end;
}

.gtin-status.valid {
    color: var(--green);
}

.gtin-status.invalid {
    color: #f87171;
}

.gs1-gtin-actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.gs1-ean13-btn {
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--blue);
    cursor: pointer;
    font-size: 0.78rem;
    padding: 4px 10px;
    transition: border-color 0.15s, background 0.15s;
}

.gs1-ean13-btn:hover {
    border-color: var(--blue);
    background: rgba(96, 165, 250, 0.08);
}

/* Landing-page Business Card Designer callout */
.feature-callout {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: 22px 24px;
    margin: 24px auto;
    max-width: 720px;
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.1), rgba(167, 139, 250, 0.1));
    border: 1px solid var(--border-hover);
    border-radius: var(--radius-lg);
    text-align: start;
}

.feature-callout .callout-badge {
    display: inline-block;
    padding: 3px 10px;
    background: var(--blue);
    color: var(--bg);
    border-radius: 4px;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    align-self: flex-start;
}

.feature-callout h2 {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--text);
    margin: 4px 0 0 0;
}

.feature-callout p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    line-height: 1.5;
    margin: 0;
}

.feature-callout .callout-link {
    color: var(--blue);
    font-weight: 600;
    text-decoration: none;
    font-size: 0.9375rem;
    margin-top: var(--space-1);
    align-self: flex-start;
}

.feature-callout .callout-link:hover {
    text-decoration: underline;
}

/* --- Mode Toggle (Generate | Scan) --- */
.mode-toggle {
    display: flex;
    justify-content: center;
    gap: var(--space-1);
    /* Reduced from 24px so the toggle visually groups with the generator
       panel it controls. Kept ~12px of breathing room above the card. */
    margin: 0 auto 12px;
    padding: var(--space-1);
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    max-width: 380px;
}

/* Simple mode hides the busy filter/search UI, category tabs, and
   non-curated types. Advanced mode shows everything (default). */
body.mode-simple .type-search,
body.mode-simple .industry-presets,
body.mode-simple .saved-profiles,
body.mode-simple .compat-legend,
body.mode-simple .type-categories,
body.mode-simple .type-categories-wrap,
body.mode-simple .compat-chip,
body.mode-simple .type-compat,
body.mode-simple .panel-tab[data-panel="batch"],
body.mode-simple .panel-tab[data-panel="export"] {
    display: none !important;
}
.tab-num {
    display: inline-block;
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
    border-radius: 50%;
    background: var(--surface-3);
    color: var(--text-muted);
    font-size: 0.7rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    margin-inline-end: 0;
}
.panel-tab.active .tab-num {
    background: var(--blue);
    color: var(--surface-1);
}
/* Invisible spacer occupies the same vertical slot as a number chip so
   un-numbered tabs (Batch) align their label with the numbered ones. */
.tab-num-spacer {
    background: transparent;
    color: transparent;
}
.panel-tab.active .tab-num-spacer {
    background: transparent;
    color: transparent;
}
body.mode-simple .type-btn:not([data-simple]) {
    display: none;
}
/* N14: when a Jobs-First tile activates a non-simple type, keep the user
   in Simple mode but surface the active type-btn so they can see what
   they picked (and click a different Simple tile to return). Only the
   active one shows; the other 95 advanced types stay hidden. The dashed
   border signals "this is an Advanced type showing in Simple", a light
   affordance that the button isn't a permanent Simple resident. */
body.mode-simple .type-btn.active:not([data-simple]) {
    display: inline-flex !important;
    order: 0;
    border-style: dashed;
}
/* Force-show all data-simple buttons regardless of the per-category `.visible`
   class that Advanced mode relies on. */
body.mode-simple .type-btn[data-simple] {
    display: inline-flex !important;
}
/* Simple-mode display order (flex `order`, doesn't touch HTML so Advanced
   mode is unaffected). URL first, WiFi second (top use case), then contact
   cluster (vCard/Email/Phone/SMS), then utility tail (Text/Event). */
body.mode-simple .type-btn[data-type="url"] { order: 1; }
body.mode-simple .type-btn[data-type="wifi"] { order: 2; }
body.mode-simple .type-btn[data-type="vcard"] { order: 3; }
body.mode-simple .type-btn[data-type="email"] { order: 4; }
body.mode-simple .type-btn[data-type="phone"] { order: 5; }
body.mode-simple .type-btn[data-type="sms"] { order: 6; }
body.mode-simple .type-btn[data-type="text"] { order: 7; }
body.mode-simple .type-btn[data-type="event"] { order: 8; }
/* In simple mode, the type selector becomes a clean single-row/wrap list
   without category filtering. */
body.mode-simple .type-selector {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.mode-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 10px 20px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.9375rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s;
}

.mode-btn:hover {
    color: var(--text);
}

.mode-btn.active {
    background: var(--blue);
    color: var(--bg);
}

/* --- Generator --- */
.generator {
    padding-bottom: var(--space-12);
}

.generator-layout {
    display: grid;
    /* minmax(0, ...) stops grid tracks from expanding based on content
       (without it, long type names / wide fields push the controls column
       wider than 50%). Locks the two columns at exactly equal widths at
       every viewport. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-8);
    align-items: start;
}

/* --- Controls Panel --- */
.controls-panel {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-width: 0;  /* allow the grid track to constrain inner content */
}

/* --- Panel Tabs (Content | Style | Export) --- */
.panel-tabs {
    display: flex;
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius) var(--radius) 0 0;
    background: var(--surface-1);
    overflow: hidden;
}

.panel-tab {
    flex: 1;
    padding: 8px 8px 10px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s;
    border-bottom: 2px solid transparent;
    /* Stack the number chip above the label so neither wraps at narrow
       widths — standard step-indicator pattern (Stripe / Material). */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.panel-tab:hover {
    color: var(--text);
    background: var(--surface-2);
}

.panel-tab.active {
    color: var(--blue);
    border-bottom-color: var(--blue);
    background: var(--surface-2);
}

/* --- Panel Content --- */
.panel-content {
    display: none;
    flex-direction: column;
    gap: var(--space-5);
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    background: var(--surface-1);
}

.panel-content.active {
    display: flex;
}

/* --- Compatibility matrix table (info page) --- */
.compat-table {
    width: 100%; border-collapse: collapse; margin: 1rem 0 1.5rem; font-size: 0.9rem;
}
.compat-table th, .compat-table td {
    border: 1px solid var(--border, #ddd); padding: 6px 10px; text-align: start;
    vertical-align: top;
}
.compat-table thead th { background: rgba(0,0,0,0.04); font-weight: 600; }
.compat-table td:nth-child(2), .compat-table td:nth-child(3), .compat-table td:nth-child(4) { text-align: center; white-space: nowrap; }
@media (max-width: 700px) {
    .compat-table,
    .vec-table,
    .compare-table,
    .proof-table,
    .print-table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Formal-statement description list used on /accessibility/. Two-column
   grid on desktop, stacked on mobile. */
.info-dl {
    display: grid;
    grid-template-columns: minmax(180px, 220px) 1fr;
    gap: 10px 20px;
    margin: 1rem 0 1.5rem;
    font-size: 0.9rem;
}
.info-dl dt { font-weight: 600; color: var(--text); }
.info-dl dd { margin: 0; color: var(--text-secondary); }
@media (max-width: 640px) {
    .info-dl { grid-template-columns: 1fr; gap: 4px 0; }
    .info-dl dt { margin-top: 10px; }
    .info-dl dt:first-of-type { margin-top: 0; }
}

/* Save-to-Pro section, supplementary, below generator */
.save-to-pro-section {
    max-width: 720px;
    margin: 32px auto 48px;
    padding: 20px 24px;
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.save-to-pro-inner { text-align: center; }
.save-to-pro-title {
    margin: 0 0 8px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-secondary);
}
.save-to-pro-hint {
    margin: 0 0 14px;
    font-size: 13px;
    color: var(--text-muted);
    line-height: 1.5;
}
.btn-save-to-pro {
    justify-content: center;
    font-weight: 500;
}
.pro-edit-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 10px 14px;
    margin-bottom: 10px;
    background: rgba(96, 165, 250, 0.08);
    border: 1px solid rgba(96, 165, 250, 0.25);
    border-radius: var(--radius, 12px);
    font-size: 0.85rem;
}
.pro-edit-banner .btn-text {
    background: none;
    border: none;
    color: var(--blue, var(--blue));
    cursor: pointer;
    font-weight: 500;
    text-decoration: underline;
    padding: 0;
    font-size: inherit;
    font-family: inherit;
}

/* Competitor comparison matrix extensions */
.compare-table th[scope="row"] {
    text-align: start;
    max-width: 360px;
    font-weight: 500;
}
.compare-table td {
    text-align: center !important;
    font-weight: 600;
    font-size: 0.85rem;
}
.compare-table .compare-yes { color: var(--green, var(--green)); }
.compare-table .compare-no { color: var(--red, #f87171); }
.compare-table .compare-partial { color: var(--amber, var(--yellow)); }
.compare-note {
    display: block;
    font-weight: 400;
    color: var(--text-muted, var(--text-muted));
    font-size: 0.78rem;
    margin-top: 2px;
    line-height: 1.4;
}

/* Pricing matrix, highlight our rows, left-align text-heavy cells */
.compare-pricing-table td {
    text-align: start !important;
    font-size: 0.82rem;
    vertical-align: top;
}
.compare-pricing-table td:nth-child(3),
.compare-pricing-table td:nth-child(4),
.compare-pricing-table td:nth-child(5),
.compare-pricing-table td:nth-child(6) {
    text-align: center !important;
    white-space: nowrap;
}
.compare-pricing-table .compare-ours {
    background: rgba(52, 211, 153, 0.08);
}
.compare-pricing-table .compare-ours td:nth-child(6) {
    color: var(--green, var(--green));
    font-weight: 700;
}
.compare-pricing-table .compare-note {
    margin-top: 0;
}

/* --- Type-fitness card (best-for / scans-on / when-not / standards) --- */
.type-fitness {
    margin: 1rem 0 0.5rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    border-radius: 12px;
    background: rgba(255,255,255,0.02);
}
.type-fitness-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.75rem 1.25rem; margin: 0; }
.type-fitness-grid > div { min-width: 0; }
.type-fitness-grid dt {
    font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted, #999); margin-bottom: 2px;
}
.type-fitness-grid dd { margin: 0; font-size: 0.85rem; line-height: 1.4; color: var(--text, var(--text)); }
.type-fitness-grid dd a { color: var(--blue, var(--blue)); text-decoration: underline; text-underline-offset: 2px; }

/* --- Privacy verifiability badge (hero) --- */
.privacy-badge {
    display: inline-flex; align-items: center; gap: var(--space-2);
    margin: 0.75rem 0 0.25rem;
    padding: 6px 14px; border-radius: 999px;
    /* Colors tuned for the site's always-dark theme. Dark forest green
       text on a faint green tint only passes WCAG AA when the page itself
       is light, which it never is, the site forces color-scheme:dark. */
    background: rgba(34,197,94,0.16);
    color: rgb(134,239,172);
    font-size: 0.82rem; font-weight: 500;
    text-decoration: none;
    border: 1px solid rgba(34,197,94,0.35);
    transition: background 0.15s;
}
.privacy-badge:hover { background: rgba(34,197,94,0.24); }
.privacy-badge-dot {
    width: 8px; height: 8px; border-radius: 50%; background: rgb(34,197,94);
    box-shadow: 0 0 0 0 rgba(34,197,94,0.5);
    animation: privacyPulse 2.4s ease-out infinite;
}
@keyframes privacyPulse {
  0% { box-shadow: 0 0 0 0 rgba(34,197,94,0.5); }
  70% { box-shadow: 0 0 0 8px rgba(34,197,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}

/* Hero trust stack, wraps the privacy-badge (primary, green pill with
   pulse) and the proof-corpus-link (secondary, blue pill) so they stack
   vertically with breathing room instead of chaining inline. Both pills
   own their own line and are centered within the hero. */
.hero-trust-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    margin: 0.75rem 0 0.25rem;
}
.hero-trust-stack .privacy-badge {
    /* Reset the badge's own margin, the stack owns spacing now. */
    margin: 0;
}

/* Proof-corpus link, secondary trust signal. Matches the privacy-badge
   pill language (same radius, same roughly-sized padding) but in a cooler
   blue palette so it reads as a sibling, not a clone. The privacy-badge
   states the claim; this one offers reproducible evidence. */
.proof-corpus-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 14px;
    font-size: 0.78rem;
    font-weight: 500;
    color: rgb(147, 197, 253);
    background: rgba(96, 165, 250, 0.08);
    border: 1px solid rgba(96, 165, 250, 0.22);
    border-radius: 999px;
    text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.proof-corpus-link:hover {
    background: rgba(96, 165, 250, 0.14);
    color: rgb(191, 219, 254);
    border-color: rgba(96, 165, 250, 0.4);
}

/* --- Industry preset packs --- */
.industry-presets {
    display: flex; align-items: center; gap: var(--space-2);
    margin-bottom: 0.5rem; font-size: 0.82rem;
    color: var(--text-muted, #999);
}
.industry-presets-label { white-space: nowrap; }
.industry-presets-select {
    padding: 5px 10px; border: 1px solid var(--border, #2a2a2a); border-radius: 8px;
    background: var(--surface-2, var(--surface-2)); color: var(--text, var(--text));
    font-size: 0.85rem; cursor: pointer;
}
.industry-presets-select:focus { outline: none; border-color: var(--accent, var(--blue)); }

/* --- Beginner/Expert mode --- */
body.mode-beginner .type-btn[data-advanced="1"]:not(.visible) { display: none; }
body.mode-beginner .type-btn[data-advanced="1"].visible { display: none; }
/* When searching in beginner mode, show matching advanced types so search is always exhaustive */
body.mode-beginner.type-search-active .type-btn[data-advanced="1"]:not([data-search-hidden="1"]) { display: inline-flex; }
.mode-toggle-btn {
    background: rgba(0,0,0,0.04); border: 1px solid var(--border, #ddd);
    color: var(--text, #111); font-size: 0.72rem; font-weight: 500;
    padding: 3px 10px; border-radius: 999px; cursor: pointer;
    margin-inline-start: 6px;
}
.mode-toggle-btn:hover { background: rgba(0,0,0,0.08); }

/* --- Compatibility legend + toggle --- */
.compat-legend { margin-bottom: 0.5rem; font-size: 0.78rem; color: var(--text-muted, #666); }
/* N19.8, Saved advanced profiles */
.saved-profiles {
    margin-top: var(--space-2);
    margin-bottom: 10px;
    padding: 8px 12px;
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.saved-profiles > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 2px 0;
    color: var(--text-muted);
    font-size: 0.8125rem;
    font-weight: 500;
    user-select: none;
}
.saved-profiles > summary::-webkit-details-marker { display: none; }
.saved-profiles > summary::before {
    content: "▸";
    display: inline-block;
    transition: transform 0.15s;
}
.saved-profiles[open] > summary::before { transform: rotate(90deg); }
.saved-profiles[open] > summary { color: var(--text); margin-bottom: var(--space-2); }
.saved-profiles-count {
    margin-inline-start: auto;
    min-width: 20px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--surface-3);
    color: var(--text-muted);
    font-size: 0.7rem;
    text-align: center;
}
.saved-profiles-body { display: flex; flex-direction: column; gap: var(--space-2); }
.saved-profiles-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.saved-profiles-list:empty { display: none; }
.saved-profile-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.8125rem;
}
.saved-profile-load {
    flex: 1;
    background: none;
    border: 0;
    padding: 0;
    text-align: start;
    cursor: pointer;
    color: var(--text);
    font: inherit;
}
.saved-profile-load:hover { text-decoration: underline; }
.saved-profile-type {
    padding: 1px 6px;
    border-radius: 10px;
    background: var(--surface-3);
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 500;
}
.saved-profile-delete {
    /* WCAG 2.2 SC 2.5.8 Target Size (Min), 24×24 CSS pixels. */
    min-width: 28px;
    min-height: 28px;
    background: none;
    border: 0;
    padding: 4px 8px;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    border-radius: 6px;
}
.saved-profile-delete:hover { color: var(--danger, #c33); background: var(--surface-3); }
.saved-profiles-empty {
    color: var(--text-muted);
    font-size: 0.8125rem;
    padding: 8px 0;
}
.saved-profiles-list:not(:empty) + .saved-profiles-empty { display: none; }
.saved-profiles-save {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8125rem;
    padding: 6px 12px;
}

.compat-legend {
    position: relative;
}
.compat-legend > summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: center; gap: var(--space-2);
    padding: 4px 0;
    padding-inline-end: 160px; /* leave room for the toggle button */
}
/* Toggle button floats top-right, visually appears on the same row as the summary */
.compat-legend > .compat-toggle-btn {
    position: absolute;
    top: 0;
    inset-inline-end: 0;
}
.compat-legend > summary::-webkit-details-marker { display: none; }
.compat-legend-summary::before { content: "▸"; display: inline-block; margin-inline-end: 6px; transition: transform 0.15s; }
.compat-legend[open] .compat-legend-summary::before { transform: rotate(90deg); }
.compat-toggle-btn {
    min-height: 28px;
    background: rgba(0,0,0,0.04); border: 1px solid var(--border, #ddd);
    color: var(--text, #111); font-size: 0.72rem; font-weight: 500;
    padding: 6px 10px; border-radius: 999px; cursor: pointer;
}
.compat-toggle-btn:hover { background: rgba(0,0,0,0.08); }
.compat-legend-grid {
    display: flex; flex-wrap: wrap; gap: 8px 16px;
    padding: 6px 0 4px 18px;
}
.compat-legend-grid span { display: inline-flex; align-items: center; gap: var(--space-1); }
.compat-legend-grid a { font-size: 0.78rem; color: var(--accent, #0070f3); text-decoration: none; }

/* --- Compatibility chips on type buttons (glyph-only by default) --- */
.compat-chip {
    display: inline-flex; align-items: center; justify-content: center;
    margin-inline-start: var(--space-1);
    font-size: 0.78rem; line-height: 1;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: rgba(0,0,0,0.06);
    vertical-align: middle;
}
/* Default: hide "universal" (most types) so chips become a real signal. */
.compat-chip.compat-universal { display: none; }
/* Toggle states (set on body via JS pref) */
body.compat-show-all .compat-chip.compat-universal { display: inline-flex; }
body.compat-show-none .compat-chip { display: none !important; }
.compat-chip.compat-universal { background: rgba(34,197,94,0.12); color: rgb(21,128,61); }
.compat-chip.compat-phone     { background: rgba(59,130,246,0.12); color: rgb(29,78,216); }
.compat-chip.compat-pro       { background: rgba(245,158,11,0.14); color: rgb(180,83,9); }
.compat-chip.compat-wallet    { background: rgba(168,85,247,0.12); color: rgb(126,34,206); }
.compat-chip.compat-auth      { background: rgba(244,63,94,0.12); color: rgb(190,18,60); }
.compat-chip.compat-app       { background: rgba(100,116,139,0.14); color: rgb(71,85,105); }
@media (prefers-color-scheme: dark) {
  .compat-chip.compat-universal { background: rgba(34,197,94,0.20); color: rgb(134,239,172); }
  .compat-chip.compat-phone     { background: rgba(59,130,246,0.20); color: rgb(147,197,253); }
  .compat-chip.compat-pro       { background: rgba(245,158,11,0.22); color: rgb(252,211,77); }
  .compat-chip.compat-wallet    { background: rgba(168,85,247,0.22); color: rgb(216,180,254); }
  .compat-chip.compat-auth      { background: rgba(244,63,94,0.22); color: rgb(252,165,165); }
  .compat-chip.compat-app       { background: rgba(100,116,139,0.24); color: rgb(203,213,225); }
}

/* --- R1: Compat detail strip (above fields for non-universal types) ---
   Appears only when the selected type has scanner limitations worth
   flagging. Source: COMPAT_DETAIL in app.js, tier from TYPE_COMPAT. */
.compat-strip {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    margin: 0 0 10px;
    padding: 8px 12px;
    font-size: 0.8rem; line-height: 1.35;
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 8px;
    background: var(--surface-2, var(--surface-2));
    color: var(--text-muted, #b0b0b0);
}
.compat-strip-chip {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    font-size: 0.85rem; line-height: 1;
    flex-shrink: 0;
}
.compat-strip-chip.compat-universal { background: rgba(34,197,94,0.14); color: rgb(21,128,61); }
.compat-strip-chip.compat-phone     { background: rgba(59,130,246,0.14); color: rgb(29,78,216); }
.compat-strip-chip.compat-pro       { background: rgba(245,158,11,0.16); color: rgb(180,83,9); }
.compat-strip-chip.compat-wallet    { background: rgba(168,85,247,0.14); color: rgb(126,34,206); }
.compat-strip-chip.compat-auth      { background: rgba(244,63,94,0.14); color: rgb(190,18,60); }
.compat-strip-chip.compat-app       { background: rgba(100,116,139,0.16); color: rgb(71,85,105); }
@media (prefers-color-scheme: dark) {
  .compat-strip-chip.compat-universal { background: rgba(34,197,94,0.22); color: rgb(134,239,172); }
  .compat-strip-chip.compat-phone     { background: rgba(59,130,246,0.22); color: rgb(147,197,253); }
  .compat-strip-chip.compat-pro       { background: rgba(245,158,11,0.24); color: rgb(252,211,77); }
  .compat-strip-chip.compat-wallet    { background: rgba(168,85,247,0.24); color: rgb(216,180,254); }
  .compat-strip-chip.compat-auth      { background: rgba(244,63,94,0.24); color: rgb(252,165,165); }
  .compat-strip-chip.compat-app       { background: rgba(100,116,139,0.26); color: rgb(203,213,225); }
}
.compat-strip-body { flex: 1 1 auto; min-width: 0; }
.compat-strip-tier { color: var(--text, var(--text)); font-weight: 600; }
.compat-strip-sep { opacity: 0.5; margin: 0 2px; }
.compat-strip-fallback a {
    color: var(--accent, var(--blue));
    text-decoration: none;
    border-bottom: 1px dashed currentColor;
}
.compat-strip-fallback a:hover { color: var(--accent-hover, #93c5fd); }
.compat-strip-link {
    color: var(--text-muted, #888);
    font-size: 0.74rem;
    text-decoration: none;
    flex-shrink: 0;
    margin-inline-start: auto;
    white-space: nowrap;
}
.compat-strip-link:hover { color: var(--accent, var(--blue)); }
/* Hide the strip in Simple mode, all Simple types are universal anyway,
   but defensive in case future Simple types aren't. */
body.mode-simple .compat-strip { display: none !important; }
/* Hide when a body class signals "compat chips off". */
body.compat-show-none .compat-strip { display: none !important; }
@media (max-width: 560px) {
  .compat-strip { font-size: 0.75rem; padding: 7px 10px; }
  .compat-strip-link { margin-inline-start: 0; }
}

/* --- Type Search --- */
.type-search { position: relative; display: flex; align-items: center; margin-bottom: 0.5rem; }
.type-search-icon { position: absolute; inset-inline-start: 10px; color: var(--text-muted, #888); pointer-events: none; }
.type-search-input {
    width: 100%; padding: 8px 32px 8px 32px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--surface-2, var(--surface-2)); color: var(--text, var(--text));
    font-size: 0.9rem; outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.type-search-input::placeholder { color: var(--text-muted, #888); opacity: 1; }
.type-search-input:focus { border-color: var(--accent, #0070f3); box-shadow: 0 0 0 3px rgba(0, 112, 243, 0.15); }
.type-search-clear {
    position: absolute; inset-inline-end: 6px;
    min-width: 28px; min-height: 28px;
    background: transparent; border: none; font-size: 1.3rem; line-height: 1;
    color: var(--text-muted, #888); cursor: pointer; padding: 4px 8px; border-radius: 6px;
}
.type-search-clear:hover { background: rgba(0,0,0,0.05); color: var(--text); }
body.type-search-active .type-categories { opacity: 0.5; pointer-events: none; }
body.type-search-active .type-btn[data-search-hidden="1"] { display: none !important; }
body.type-search-active .type-selector .type-btn { display: inline-flex; }
body.type-search-active .field-group.active { display: none; }

/* --- Landing pages: hide app-only UI elements ---
   body[data-qr-preselect] is set on generated landing pages (e.g. /wifi-qr-code/).
   The search bar, mode toggle, compat legend, and industry presets are
   generator-mode UI only, they don't work on landing pages and look broken. */
body[data-qr-preselect] .type-search,
body[data-qr-preselect] .mode-toggle,
body[data-qr-preselect] .compat-legend,
body[data-qr-preselect] .industry-presets { display: none !important; }

/* --- Type Categories --- */
/* Horizontally-scrollable category strip.
 * Clean look on both desktop and mobile:
 *   - scrollbar is hidden
 *   - smooth momentum scrolling on iOS/touch
 *   - fade edges appear dynamically (left when scrolled, right when more
 *     content exists) via JS toggling .can-scroll-left / .can-scroll-right
 *   - mouse wheel is translated into horizontal scroll in JS for discoverability
 */
.type-categories-wrap {
    position: relative;
    margin-bottom: var(--space-1);
}
.type-categories {
    display: flex;
    gap: var(--space-1);
    overflow-x: auto;
    scrollbar-width: none;            /* Firefox */
    -ms-overflow-style: none;         /* legacy IE/Edge */
    -webkit-overflow-scrolling: touch;/* momentum scroll on iOS */
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    padding: 2px 0;
}
.type-categories::-webkit-scrollbar { display: none; }

/* Fade indicators, absolute-positioned overlays on the wrapper.
 * Visibility driven by JS-applied classes on .type-categories so they
 * only show when there's actually more content in that direction. */
.type-categories-wrap::before,
.type-categories-wrap::after {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    width: 28px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
    z-index: 1;
}
.type-categories-wrap::before {
    inset-inline-start: 0;
    background: linear-gradient(to right, var(--bg, #08090a), transparent);
}
.type-categories-wrap::after {
    inset-inline-end: 0;
    background: linear-gradient(to left, var(--bg, #08090a), transparent);
}
.type-categories.can-scroll-left ~ .fade-left,
.type-categories-wrap.can-scroll-left::before { opacity: 1; }
.type-categories-wrap.can-scroll-right::after { opacity: 1; }

.cat-btn {
    flex-shrink: 0;               /* no compression in the flex row */
    scroll-snap-align: start;     /* snap to the leading edge when user flicks */
}

/* Scroll arrow buttons, desktop-only explicit affordance.
 * Research (NNG 2022, YouTube/Netflix/Amazon pattern): horizontal scroll
 * discoverability on desktop mouse is ~40% without controls, ~75% with
 * fade, ~92% with visible arrows. Touch users never need them (swipe is
 * native), so hide entirely on touch via @media (hover) + (pointer: fine).
 */
.cat-scroll-btn {
    display: none; /* shown only on pointer-capable devices below */
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 28px;
    height: 28px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--surface-2);
    border: 1px solid var(--border-hover);
    color: var(--text);
    cursor: pointer;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, background 0.15s ease, border-color 0.15s ease;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    padding: 0;
}
.cat-scroll-btn.left { inset-inline-start: 2px; }
.cat-scroll-btn.right { inset-inline-end: 2px; }
.cat-scroll-btn:hover { background: var(--surface-3); border-color: var(--blue); }
.cat-scroll-btn:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
    opacity: 1 !important;
    pointer-events: auto !important;
}
.type-categories-wrap.can-scroll-left .cat-scroll-btn.left,
.type-categories-wrap.can-scroll-right .cat-scroll-btn.right {
    opacity: 1;
    pointer-events: auto;
}
@media (hover: hover) and (pointer: fine) {
    .cat-scroll-btn { display: flex; }
}

.cat-btn {
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: 20px;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s;
}

.cat-btn:hover {
    border-color: var(--border-hover);
    color: var(--text);
}

.cat-btn.active {
    border-color: var(--blue);
    color: var(--blue);
    background: rgba(96, 165, 250, 0.08);
}

/* --- Type Selector --- */
.type-selector {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.type-btn {
    display: none;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 0.875rem;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s;
}

.type-btn.visible {
    display: flex;
}

.type-btn:hover {
    border-color: var(--border-hover);
    color: var(--text);
    background: var(--surface-3);
}

.type-btn.active {
    border-color: var(--blue);
    color: var(--blue);
    background: rgba(96, 165, 250, 0.08);
}

/* --- Input Fields --- */
.field-group {
    /* Inactive groups use display:none, this matches the known-working state
       (commit ade012e9e). Off-screen variants caused autofill to fail because
       Chrome's classifier saw dozens of duplicate inputs (multiple name="email"
       / name="tel" across every type's hidden field-group) and refused to
       autofill the ambiguous form. Modern Chrome dynamically rescans inputs
       when display changes, so display:none does NOT break autofill on the
       active group. */
    display: none;
    flex-direction: column;
    gap: var(--space-3);
}

.field-group.active {
    position: static;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    width: 100%;
    height: auto;
    overflow: visible;
    opacity: 1;
    pointer-events: auto;
}

.field-group label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.field-group input:not([type="checkbox"]):not([type="file"]):not([type="color"]),
.field-group textarea,
.field-group select {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.9375rem;
    font-family: inherit;
    transition: border-color 0.2s, box-shadow 0.2s;
    outline: none;
}

.field-group input:focus,
.field-group textarea:focus,
.field-group select:focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.1);
}

.field-group input::placeholder,
.field-group textarea::placeholder {
    color: var(--text-muted);
}

.field-group textarea {
    resize: vertical;
    min-height: 80px;
}

/* === GLOBAL FORM ELEMENT BASELINES =====================================
   These rules fix native browser inconsistencies (checkbox, range, color,
   select chevron) so every form control matches the dark accent UI even
   when not inside a styled container. Per-container rules (.field-group,
   .card-text-row, .card-color-row, etc.) override where needed. */

/* Checkboxes, native OS look replaced with custom dark-themed square */
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    margin: 0;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--surface-2);
    cursor: pointer;
    vertical-align: middle;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
    flex-shrink: 0;
    position: relative;
}
input[type="checkbox"]:hover {
    border-color: var(--blue);
}
input[type="checkbox"]:checked {
    background: var(--blue);
    border-color: var(--blue);
}
input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    inset: 0;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2308090a' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/12px no-repeat;
}
input[type="checkbox"]:focus-visible {
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.25);
    outline: none;
}

/* Radio buttons, same custom treatment, circular */
input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    margin: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface-2);
    cursor: pointer;
    vertical-align: middle;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
    flex-shrink: 0;
    position: relative;
}
input[type="radio"]:hover { border-color: var(--blue); }
input[type="radio"]:checked {
    border-color: var(--blue);
    background: radial-gradient(circle, var(--blue) 0 5px, var(--surface-2) 6px 100%);
}
input[type="radio"]:focus-visible {
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.25);
    outline: none;
}

/* Range sliders, fully custom track + thumb (zero CSS before this) */
input[type="range"] {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    height: 6px;
    background: var(--border);
    border-radius: 3px;
    cursor: pointer;
    outline: none;
    margin: 8px 0;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--blue);
    border: 2px solid var(--bg);
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    transition: transform 0.15s, box-shadow 0.15s;
}
input[type="range"]::-webkit-slider-thumb:hover {
    transform: scale(1.15);
    box-shadow: 0 2px 8px rgba(96, 165, 250, 0.5);
}
input[type="range"]::-moz-range-thumb {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--blue);
    border: 2px solid var(--bg);
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
input[type="range"]::-moz-range-track {
    height: 6px;
    background: var(--border);
    border-radius: 3px;
}

/* Color pickers, consistent compact swatch */
input[type="color"] {
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.15s, box-shadow 0.15s;
}
input[type="color"]:hover {
    border-color: var(--blue);
}
input[type="color"]:focus-visible {
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.25);
    outline: none;
}
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch {
    border: none;
    border-radius: 6px;
}
input[type="color"]::-moz-color-swatch {
    border: none;
    border-radius: 6px;
}

/* Native chevron + dark options for selects everywhere (overridden by
   .field-group select etc. for sizing) */
select {
    color-scheme: dark;
}
select option {
    background: var(--surface-2);
    color: var(--text);
}

/* Textareas resize vertically only, never horizontally */
textarea { resize: vertical; }

/* Industry-preset select needs an explicit chevron + dark option */
.industry-presets-select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 14px;
    padding-inline-end: var(--space-8);
}

/* Consistent calendar/time pickers across all date-like inputs.
   `color-scheme: dark` makes the native picker UI dark-themed on
   macOS/iOS/Windows so it matches our app's dark palette. The picker
   indicator (calendar icon) is restyled to match our blue accent. */
.field-group input[type="date"],
.field-group input[type="datetime-local"],
.field-group input[type="time"],
.field-group input[type="month"],
.field-group input[type="week"] {
    /* color-scheme:light forces Chrome to render the BLACK native indicator
       which we then invert to white via filter. Trade-off accepted: the
       picker popup renders in light theme. Tried color-scheme:dark + custom
       background-image overlay, icon never showed and click broke. The
       light/inverted approach is the only one that reliably renders a
       visible AND clickable calendar icon across Chrome / Edge / Safari. */
    color-scheme: light;
    font-variant-numeric: tabular-nums;
    padding-inline-end: 14px;
}
.field-group input[type="date"]::-webkit-calendar-picker-indicator,
.field-group input[type="datetime-local"]::-webkit-calendar-picker-indicator,
.field-group input[type="time"]::-webkit-calendar-picker-indicator,
.field-group input[type="month"]::-webkit-calendar-picker-indicator,
.field-group input[type="week"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    filter: invert(1);
    opacity: 0.65;
    transition: opacity 0.15s;
}
.field-group input[type="date"]:hover::-webkit-calendar-picker-indicator,
.field-group input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator,
.field-group input[type="time"]:hover::-webkit-calendar-picker-indicator,
.field-group input[type="month"]:hover::-webkit-calendar-picker-indicator,
.field-group input[type="week"]:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
}

.field-group input[type="number"] {
    -moz-appearance: textfield;
}

.field-group input[type="number"]::-webkit-inner-spin-button {
    opacity: 0.5;
}

.field-group select {
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-inline-end: 36px;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: 0.875rem;
    color: var(--text-muted);
    cursor: pointer;
}

.checkbox-label input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--blue);
}

.char-count {
    font-size: 0.75rem;
    color: var(--text-muted);
    text-align: end;
}

.field-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    font-style: italic;
}

.transparent-toggle {
    margin-inline-start: var(--space-1);
    font-size: 0.75rem;
    white-space: nowrap;
}

.transparent-toggle input[type="checkbox"] {
    width: 14px;
    height: 14px;
}

/* --- vCard Photo Preview --- */
.vcard-photo-preview {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    overflow: hidden;
    border: 2px solid var(--border-hover);
    background: var(--surface-2);
}

.vcard-photo-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Local file upload, styled inline file input */
.upload-label {
    margin-top: 6px;
}

.file-input-styled {
    display: block;
    width: 100%;
    padding: 8px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-muted);
    font-size: 0.8125rem;
    font-family: inherit;
    cursor: pointer;
}

.file-input-styled::file-selector-button {
    margin-inline-end: 10px;
    padding: 4px 10px;
    background: var(--surface-3);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.75rem;
    cursor: pointer;
}

.file-input-styled:hover::file-selector-button {
    background: var(--blue);
    color: var(--bg);
    border-color: var(--blue);
}

/* Section heading + lead used by the new Batch panel */
.section-heading {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--text);
    margin: 0 0 6px 0;
}

.section-lead {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin: 0 0 8px 0;
    line-height: 1.5;
}

.section-lead + .field-hint code,
.field-hint code {
    background: var(--surface-3);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 0.75rem;
}

/* Collapsible "More fields (optional)" section in form groups */
.extra-fields {
    margin-top: var(--space-3);
    padding: 10px 14px;
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.extra-fields > summary {
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.8125rem;
    font-weight: 500;
    list-style: none;
    padding: 4px 0;
    user-select: none;
}

.extra-fields > summary::-webkit-details-marker {
    display: none;
}

.extra-fields > summary::before {
    content: "▸";
    display: inline-block;
    margin-inline-end: 6px;
    transition: transform 0.15s;
}

.extra-fields[open] > summary::before {
    transform: rotate(90deg);
}

.extra-fields[open] > summary {
    color: var(--text);
    margin-bottom: 6px;
}

.extra-fields-subhead {
    margin-top: 14px;
    margin-bottom: var(--space-1);
    color: var(--text-muted);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

/* N19.9, Capability banner on non-QR formats. Chip + title + desc so the
   constraint is visible, not just textual. */
.capability-banner {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: 10px 12px;
    background: var(--surface-2, #1a1a1a);
    border: 1px solid var(--border, #2a2a2a);
    border-inline-start: 3px solid var(--text-muted, #999);
    border-radius: 8px;
}
.capability-banner-chip {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--surface-3, #262626);
    font-size: 1rem;
}
.capability-banner-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.capability-banner-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text);
}
.capability-banner-desc {
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* N19.11, Failure education at moment of choice. Terse "use this if /
   do not use" callout at the top of field-heavy forms, before any input.
   Two short clauses, orange-accented strong tags, small badge icon. */
.use-if-callout {
    margin: 0 0 14px 0;
    padding: 10px 12px;
    background: var(--surface-2, #1a1a1a);
    border-inline-start: 3px solid var(--accent, var(--amber));
    border-radius: 6px;
    color: var(--text);
    font-size: 0.8125rem;
    line-height: 1.5;
}
.use-if-callout strong {
    color: var(--accent, var(--amber));
    font-weight: 600;
}

/* N19.3, Progressive disclosure sections inside advanced generators.
   Reuses .extra-fields CSS for layout; data-level gives semantic accent. */
.field-section {
    margin-top: var(--space-3);
}
.field-section[data-level="recommended"] {
    border-inline-start: 2px solid var(--accent, #7c5cff);
    border-top: none;
    border-inline-end: none;
    border-bottom: none;
    border-radius: 0;
    padding: 2px 0 2px 12px;
    background: transparent;
}
.field-section[data-level="recommended"] > summary {
    color: var(--text);
}
.field-section[data-level="expert"] > summary::after {
    content: "";
    display: inline-block;
    margin-inline-start: var(--space-2);
    padding: 1px 6px;
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 500;
    vertical-align: 1px;
}
.field-section[data-level="expert"]:not([open]) > summary::after {
    content: "expert";
}
.field-section[data-level="expert"][open] > summary::after {
    content: "expert";
    opacity: 0.6;
}

/* --- Style Panel Sections --- */
.style-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--border);
}

.style-section:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.section-label {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* --- Template Grid --- */
.template-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
}

.template-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
    padding: 6px;
    border: 2px solid var(--border);
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
    transition: all 0.2s;
}

.template-btn:hover {
    border-color: var(--border-hover);
}

.template-btn.active {
    border-color: var(--blue);
}

.template-preview {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.template-preview > svg {
    width: 90%;
    height: 90%;
}

.template-name {
    font-size: 0.625rem;
    color: var(--text-muted);
    font-family: inherit;
}

.template-actions {
    display: flex;
    gap: 6px;
    margin-top: var(--space-2);
    flex-wrap: wrap;
}

/* Center logo preset grid */
.logo-preset-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 6px;
    margin-top: 6px;
}

#logo-preset-search {
    width: 100%;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text);
    font-size: 13px;
    padding: 9px 12px 9px 34px;
    margin-bottom: var(--space-2);
    outline: none;
    transition: border-color 0.15s, background 0.15s;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='8'/><path d='m21 21-4.3-4.3'/></svg>");
    background-repeat: no-repeat;
    background-position: 10px center;
    background-size: 16px 16px;
}
#logo-preset-search::placeholder { color: var(--text-muted); }
#logo-preset-search:focus {
    border-color: var(--blue);
    background-color: var(--surface-3);
}
#logo-preset-search::-webkit-search-cancel-button {
    -webkit-appearance: none;
    height: 14px; width: 14px;
    background: var(--text-muted);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M18 6L6 18M6 6l12 12' stroke='black' stroke-width='3' stroke-linecap='round'/></svg>") center/contain no-repeat;
    cursor: pointer;
}
#logo-preset-empty {
    text-align: center;
    padding: var(--space-3);
    margin: 8px 0 0;
    background: var(--surface-2);
    border: 1px dashed var(--border);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 13px;
}

.logo-preset-more-wrap {
    margin-top: var(--space-2);
}

.logo-preset-more-wrap > summary {
    cursor: pointer;
    color: var(--text-muted);
    font-size: 13px;
    padding: 6px 0;
    user-select: none;
    list-style: none;
}

.logo-preset-more-wrap > summary::-webkit-details-marker {
    display: none;
}

.logo-preset-more-wrap > summary::before {
    content: "\25B8 ";
    display: inline-block;
    transition: transform 0.15s;
}

.logo-preset-more-wrap[open] > summary::before {
    transform: rotate(90deg);
}

.logo-preset-more-wrap > summary:hover {
    color: var(--text);
}

/* Light neutral tiles regardless of theme — like an app drawer. Dark
   icon fills (twemoji greys, brand blacks, hand-crafted dark slates)
   read against the tile; brand-tinted icons render in their own color.
   currentColor inherits the dark text so mono and dark-tint fallbacks
   render dark on the light tile. */
.logo-preset-btn {
    aspect-ratio: 1;
    background: var(--surface-tile);
    border: 1px solid var(--tile-border);
    border-radius: var(--radius);
    color: var(--on-tile);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}

.logo-preset-btn:hover {
    border-color: var(--blue);
    background: var(--surface-tile-hover);
    transform: translateY(-1px);
}

.logo-preset-btn.active {
    border-color: var(--blue);
    background: rgba(96, 165, 250, 0.18);
}

.logo-preset-btn svg {
    width: 100%;
    height: 100%;
}

/* "Show more templates" collapsible */
.templates-more {
    margin-top: var(--space-2);
}

.templates-more > summary {
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.75rem;
    text-align: center;
    padding: 6px 8px;
    background: var(--surface-1);
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    list-style: none;
    user-select: none;
    transition: border-color 0.15s, color 0.15s;
}

.templates-more > summary::-webkit-details-marker {
    display: none;
}

.templates-more > summary:hover {
    border-color: var(--blue);
    color: var(--text);
}

.templates-more[open] > summary {
    margin-bottom: var(--space-2);
}

.templates-more #template-grid-more {
    margin-top: 0;
}

/* My Styles empty state */
#my-styles-empty {
    margin-top: var(--space-1);
    margin-bottom: var(--space-2);
}

#my-styles-grid:not(:empty) + .template-actions {
    margin-top: 10px;
}

#my-styles-grid:empty + .template-actions {
    margin-top: var(--space-2);
}

#my-styles-grid:not(:empty) ~ #my-styles-empty,
#my-styles-section #my-styles-grid:not(:empty) ~ #my-styles-empty {
    display: none;
}

/* --- Color Rows --- */
.color-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.color-row label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.color-input-wrap {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.color-input-wrap input[type="color"] {
    width: 32px;
    height: 32px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: none;
    cursor: pointer;
    padding: 2px;
}

.color-input-wrap input[type="color"]:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.color-hex {
    font-size: 0.75rem;
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--text-muted);
    min-width: 60px;
}

.color-row select {
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.8125rem;
    font-family: inherit;
    cursor: pointer;
    outline: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    padding-inline-end: 28px;
}

.gradient-options {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--surface-2);
    border-radius: 8px;
}

/* --- Frame Text --- */
.frame-text-input {
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.8125rem;
    font-family: inherit;
    outline: none;
    width: 160px;
    transition: border-color 0.2s;
}

.frame-text-input:focus {
    border-color: var(--blue);
}

.frame-text-input::placeholder {
    color: var(--text-muted);
}

/* --- Logo Upload --- */
.logo-upload {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.logo-upload > label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.logo-upload-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.logo-name {
    font-size: 0.75rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 120px;
}

/* --- Export Panel --- */
.export-buttons {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.export-buttons .btn {
    justify-content: center;
}

/* N5, QR Lab chip inline with the download buttons so verification is
   one glance away, not an extra nav hop. */
.export-lab-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    padding: 6px 10px;
    border-radius: 999px;
    border: 1px dashed var(--border, #2a2a2a);
    background: transparent;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.78rem;
    font-weight: 500;
    align-self: flex-start;
    transition: color 0.12s, border-color 0.12s;
}
.export-lab-chip:hover,
.export-lab-chip:focus-visible {
    color: var(--accent, #7c5cff);
    border-color: var(--accent, #7c5cff);
    border-style: solid;
}

/* --- Batch Progress --- */
.batch-progress {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

.batch-bar {
    flex: 1;
    height: 6px;
    background: var(--surface-3);
    border-radius: 3px;
    overflow: hidden;
}

.batch-bar-fill {
    height: 100%;
    width: 0%;
    background: var(--blue);
    border-radius: 3px;
    transition: width 0.2s;
}

.batch-status {
    font-size: 0.75rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.batch-results {
    margin-top: var(--space-3);
    padding: var(--space-3);
    background: var(--surface-2);
    border-radius: 10px;
    border: 1px solid var(--border);
}

.batch-results-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.batch-results-count {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text);
}

.batch-preview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 10px;
    max-height: 460px;
    overflow-y: auto;
    padding: 6px;
    /* Custom scrollbar, Firefox */
    scrollbar-width: thin;
    scrollbar-color: var(--border-hover) var(--surface-2);
}

/* Custom scrollbar, Chromium / Safari */
.batch-preview-grid::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
.batch-preview-grid::-webkit-scrollbar-track {
    background: var(--surface-2);
    border-radius: 6px;
}
.batch-preview-grid::-webkit-scrollbar-thumb {
    background: var(--border-hover);
    border-radius: 6px;
    border: 2px solid var(--surface-2);
}
.batch-preview-grid::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
}

.batch-preview-item {
    position: relative;
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
    background: var(--surface-3);
    border: 1px solid var(--border);
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.batch-preview-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
    border-color: var(--blue);
}

.batch-preview-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 6px;
}

.batch-preview-item .batch-preview-label {
    position: absolute;
    bottom: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    font-size: 0.6875rem;
    text-align: center;
    padding: 4px 6px;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.4));
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.batch-preview-num {
    position: absolute;
    top: var(--space-1);
    inset-inline-start: var(--space-1);
    background: var(--blue);
    color: var(--bg);
    font-size: 0.625rem;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 10px;
    line-height: 1;
}

.batch-zoom-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: rgba(0,0,0,0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: default;
    animation: fadeIn 0.15s ease;
    overflow: hidden;
}

.batch-zoom-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
}

.batch-zoom-content img {
    max-width: 90vw;
    max-height: 80vh;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.5);
    cursor: zoom-in;
    transition: transform 0.1s ease;
}

.qr-modal-canvas svg {
    display: block;
    cursor: zoom-in;
    transition: transform 0.1s ease;
}

.batch-zoom-label {
    font-size: 0.9rem;
    color: #fff;
    font-weight: 600;
}

/* --- Colorblind Filter --- */
.qr-preview.cb-protanopia .qr-canvas-wrap {
    filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='p'><feColorMatrix type='matrix' values='0.567,0.433,0,0,0 0.558,0.442,0,0,0 0,0.242,0.758,0,0 0,0,0,1,0'/></filter></svg>#p");
}

.qr-preview.cb-deuteranopia .qr-canvas-wrap {
    filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='d'><feColorMatrix type='matrix' values='0.625,0.375,0,0,0 0.7,0.3,0,0,0 0,0.3,0.7,0,0 0,0,0,1,0'/></filter></svg>#d");
}

.qr-preview.cb-tritanopia .qr-canvas-wrap {
    filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='t'><feColorMatrix type='matrix' values='0.95,0.05,0,0,0 0,0.433,0.567,0,0 0,0.475,0.525,0,0 0,0,0,1,0'/></filter></svg>#t");
}

/* --- Shortcuts List --- */
.shortcuts-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.shortcut-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.shortcut-row span {
    margin-inline-start: auto;
}

kbd {
    display: inline-block;
    padding: 2px 6px;
    background: var(--surface-3);
    border: 1px solid var(--border-hover);
    border-radius: 4px;
    font-size: 0.6875rem;
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--text-secondary);
    line-height: 1.4;
}

/* --- Preview Panel --- */
.preview-panel {
    position: sticky;
    top: var(--space-20);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.qr-preview {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-8);
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 340px;
    transition: border-color 0.3s;
}

.qr-preview.has-qr {
    border-color: var(--border-hover);
    cursor: zoom-in;
}

.qr-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    color: var(--text-muted);
    text-align: center;
    font-size: 0.875rem;
}

.qr-canvas-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: var(--radius);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
    overflow: hidden;
    animation: qrFadeIn 0.3s ease;
}

@keyframes qrFadeIn {
    from { opacity: 0; transform: scale(0.95); }
    to { opacity: 1; transform: scale(1); }
}

#qr-canvas {
    max-width: 100%;
    height: auto;
    display: block;
}

/* --- Quick Actions (below preview) --- */
.quick-actions {
    display: flex;
    gap: var(--space-2);
}

.quick-actions .btn {
    flex: 1;
    justify-content: center;
}

/* N19.6, In-generator preview-realism toggle. Non-destructive: applies
   CSS filters / transforms to the live preview via data-preview-mode on
   #qr-preview. No payload or encoder change. */
.preview-realism {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}
.preview-realism-chip {
    flex: 1 1 auto;
    padding: 6px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.preview-realism-chip:hover {
    border-color: var(--border-hover);
    color: var(--text);
}
.preview-realism-chip.active {
    background: var(--accent, #7c5cff);
    border-color: var(--accent, #7c5cff);
    color: #fff;
}
/* The filters themselves, applied to the preview wrapper when a chip is
   active. transform-origin center keeps the scaled "phone" preview in
   place rather than anchoring top-left. */
.qr-preview { transition: filter 0.2s, transform 0.2s; transform-origin: center; }
.qr-preview[data-preview-mode="phone"] {
    transform: scale(0.55);
}
.qr-preview[data-preview-mode="mono"] {
    filter: grayscale(1) contrast(1.08);
}
.qr-preview[data-preview-mode="low-contrast"] {
    filter: contrast(0.52) brightness(1.15);
}
.qr-preview[data-preview-mode="packaging"] {
    /* Approximates a QR printed onto a small product label viewed from
       reading distance, tests whether fine styling still reads at
       reduced absolute size. */
    transform: scale(0.35);
}
.qr-preview[data-preview-mode="damaged"] {
    /* Reduced contrast + saturation + a pixelated-noise overlay to
       simulate scuffed print, partial occlusion, or cheap scanner
       input. A QR that still decodes here has real ECC margin. */
    filter: contrast(0.72) saturate(0.9);
    position: relative;
}
.qr-preview[data-preview-mode="damaged"]::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        repeating-linear-gradient(45deg, rgba(0,0,0,0.08) 0 2px, transparent 2px 7px),
        repeating-linear-gradient(-45deg, rgba(255,255,255,0.06) 0 2px, transparent 2px 5px);
    mix-blend-mode: overlay;
    pointer-events: none;
}

/* --- History Panel --- */
.history-panel {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-1);
    padding: var(--space-3);
}

.history-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-2);
}

.btn-text {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.75rem;
    font-family: inherit;
    cursor: pointer;
    transition: color 0.2s;
}

.btn-text:hover {
    color: var(--pink);
}

.history-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-2);
}

.history-item {
    aspect-ratio: 1;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.2s;
    padding: var(--space-1);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.history-item:hover {
    border-color: var(--blue);
}

.history-item img {
    width: 100%;
    flex: 1;
    min-height: 0;
    object-fit: contain;
    display: block;
}

.history-item-type {
    font-size: 10px;
    line-height: 1.1;
    text-align: center;
    color: var(--text-2);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- Buttons --- */
.btn-sm {
    padding: 6px 12px;
    font-size: 0.8125rem;
}

.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 10px 18px;
    border-radius: var(--radius);
    font-size: 0.875rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s;
    border: none;
    text-decoration: none;
    white-space: nowrap;
}

.btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.btn-primary {
    background: var(--blue);
    color: #08090a;
}

.btn-primary:hover:not(:disabled) {
    background: #7db8fb;
    transform: translateY(-1px);
}

.btn-secondary {
    background: var(--surface-2);
    color: var(--text);
    border: 1px solid var(--border);
}

.btn-secondary:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: var(--border-hover);
    transform: translateY(-1px);
}

.btn-outline {
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border);
}

.btn-outline:hover:not(:disabled) {
    color: var(--text);
    border-color: var(--border-hover);
    background: var(--surface-1);
}

/* Surprise-me random-template button — distinct from neutral outline
   buttons so users can spot it next to the Quick Templates header.
   Gradient + slight glow + accent ring on hover so it reads as an
   action invitation, not a passive label. */
#btn-random-template {
    background: linear-gradient(135deg, var(--yellow) 0%, #f97316 60%, #ec4899 100%);
    border: 1px solid transparent;
    color: var(--on-tile);
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(249, 115, 22, 0.4);
}
#btn-random-template:hover:not(:disabled) {
    background: linear-gradient(135deg, #fcd34d 0%, #fb923c 60%, #f472b6 100%);
    color: #111827;
    box-shadow: 0 2px 8px rgba(249, 115, 22, 0.55);
    transform: translateY(-1px);
}
#btn-random-template svg {
    color: var(--on-tile);
}

/* Caption-text toggle row above the frame-text input. Checkbox-style
   so the choice is obvious and the input only appears when wanted. */
.caption-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.875rem;
    user-select: none;
}
.caption-toggle input[type="checkbox"] {
    width: 16px;
    height: 16px;
    cursor: pointer;
    accent-color: var(--blue);
}
.caption-toggle:hover { color: var(--text); }

/* Any-character / emoji input — pairs with the preset grid so users can
   pick from the curated list OR type any Unicode character (emoji,
   letter, symbol) and have it become the center logo at the right
   size. Effectively expands the catalog to all of Unicode. */
.logo-char-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--border);
}
.logo-char-row label {
    color: var(--text-muted);
    font-size: 0.85rem;
    white-space: nowrap;
}
/* Mutually-exclusive logo-source tabs: 'Pick icon' vs 'Type character'.
   Picking one clears the other (enforced in JS) — only one source can
   drive the QR center logo at a time. */
/* Per-symbology capability gating: when the active type doesn't
   support a given style control (e.g. dot-shape on a 1D barcode),
   _applyCapabilitiesForType adds .cap-hidden to the wrapping row. */
.cap-hidden { display: none !important; }

.logo-source-tabs {
    display: flex;
    gap: 4px;
    margin-top: 8px;
    margin-bottom: 12px;
    padding: 4px;
    background: var(--surface-2);
    border-radius: var(--radius);
}
.logo-source-tab {
    flex: 1;
    padding: 8px 12px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    border-radius: calc(var(--radius) - 2px);
    transition: background 0.15s, color 0.15s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.logo-source-tab svg { flex-shrink: 0; }
.logo-tab-emoji {
    font-size: 16px;
    line-height: 1;
    flex-shrink: 0;
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla', system-ui, sans-serif;
}
.logo-char-samples {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 6px;
    margin-top: 8px;
}
.logo-char-sample {
    font-size: 20px;
    line-height: 1;
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-1);
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease;
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla', system-ui, sans-serif;
}
.logo-char-sample:hover {
    border-color: var(--blue);
    background: var(--surface-tile-hover);
}
.logo-char-sample:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}
.logo-source-tab:hover {
    color: var(--text);
}
.logo-source-tab.active {
    background: var(--surface-1);
    color: var(--blue);
}
.logo-source-panel {
    margin-top: 4px;
}
/* Big tile-style input matching the icon picker so the typed
   character/emoji renders at the same visual size as picker icons. */
.logo-char-tile-wrap {
    display: flex;
    justify-content: center;
    margin: 12px 0;
}
.logo-char-tile {
    width: 96px;
    height: 96px;
    aspect-ratio: 1;
    text-align: center;
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla', system-ui, sans-serif;
    font-size: 3.5rem;
    /* line-height matches box height so the single grapheme sits visually
       centered. Default text-input alignment is top, which left ~40px
       of empty space below the glyph in a 96px tile. */
    line-height: 96px;
    padding: 0;
    border: 1px solid var(--tile-border);
    border-radius: var(--radius);
    background: var(--surface-tile);
    color: var(--on-tile);
    cursor: text;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.logo-char-tile:focus {
    border-color: var(--blue);
    background: var(--surface-tile-hover);
    outline: none;
    transform: translateY(-1px);
}
.logo-char-tile:hover { background: var(--surface-tile-hover); }
.logo-char-controls {
    display: flex;
    justify-content: center;
    gap: 16px;
    flex-wrap: wrap;
}
.logo-char-control {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 0.85rem;
    cursor: pointer;
}
.logo-char-control input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--blue);
}
.logo-char-tile-clear {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    width: 22px;
    height: 22px;
    line-height: 1;
    padding: 0;
    border-radius: 50%;
    cursor: pointer;
    font-size: 1rem;
}
.logo-char-tile-clear:hover {
    color: var(--text);
    border-color: var(--text-muted);
}
.logo-char-style {
    display: inline-flex;
    gap: 2px;
}
.logo-char-style-btn {
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
}
.logo-char-style-btn:hover {
    color: var(--text);
}
.logo-char-style-btn[aria-pressed="true"] {
    background: var(--blue);
    border-color: var(--blue);
    color: #ffffff;
}
.logo-char-color {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: transparent;
    cursor: pointer;
}
.logo-char-color:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.logo-char-tile-row {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 0.85rem;
    cursor: pointer;
}
.logo-char-tile-row input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--blue);
}

.btn-gradient {
    background: linear-gradient(135deg, var(--blue), var(--purple));
    color: #fff;
    font-weight: 600;
}

.btn-gradient:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 20px rgba(96, 165, 250, 0.3);
}

/* --- Sign CTA --- */
.sign-cta {
    padding: 48px 0;
}

.sign-cta-inner {
    padding: var(--space-8);
    border: 1px solid rgba(96, 165, 250, 0.15);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.05), rgba(167, 139, 250, 0.05));
    overflow: hidden;
    position: relative;
}

.sign-cta-badge {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: var(--space-5);
}

.sign-cta-body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-10);
}

.sign-cta-content {
    display: flex;
    flex-direction: column;
    gap: 14px;
    flex: 1;
}

.sign-cta h2 {
    font-size: clamp(1.25rem, 3vw, 1.625rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.3;
}

.sign-cta p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    line-height: 1.6;
    max-width: 440px;
}

.sign-features {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 4px 0;
}

.sign-features li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.sign-features svg {
    flex-shrink: 0;
}

.sign-cta .btn-gradient {
    align-self: flex-start;
    margin-top: var(--space-1);
}

.sign-cta-visual {
    flex-shrink: 0;
}

.sign-doc-mock {
    width: 160px;
    padding: var(--space-5);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.sign-doc-line {
    height: 6px;
    background: var(--surface-3);
    border-radius: 3px;
    width: 100%;
}

.sign-doc-line-title {
    height: 8px;
    width: 60%;
    background: rgba(96, 165, 250, 0.2);
}

.sign-doc-line-short {
    width: 70%;
}

.sign-doc-spacer {
    height: 8px;
}

.sign-doc-sig {
    margin-top: var(--space-1);
    padding-top: var(--space-2);
    border-top: 1px dashed var(--border-hover);
    display: flex;
    justify-content: center;
}

/* --- Why Abundera QR ---
   Post-generator "why us" block holding the trust-strip + hero-features
   that used to live above the fold. Centered stack, compact padding so
   it reads as a supporting section, not a marketing slab. */
.hero-proof-footer {
    padding: 32px 0 16px;
    text-align: center;
    max-width: 1120px;
    margin: 0 auto;
}
.hero-proof-footer .hero-proof-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.02em;
    margin: 0 0 16px;
}
/* trust-strip and hero-features already have centered layouts via their
   own class rules, only the wrapper needs the section layout. */
.hero-proof-footer .trust-strip,
.hero-proof-footer .hero-features {
    margin-inline-start: auto;
    margin-inline-end: auto;
}

/* --- How It Works --- */
.how-it-works {
    padding: 40px 0;
    text-align: center;
}

.how-it-works h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: var(--space-8);
    letter-spacing: -0.02em;
}

.steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
}

.step {
    padding: var(--space-6);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    transition: border-color 0.2s;
}

.step:hover {
    border-color: var(--border-hover);
}

.step-number {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: rgba(96, 165, 250, 0.1);
    color: var(--blue);
    font-weight: 700;
    font-size: 0.875rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-3);
}

.step h3 {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 6px;
}

.step p {
    color: var(--text-muted);
    font-size: 0.875rem;
}

/* --- Languages showcase --- */
.languages-showcase {
    padding: 32px 0 16px;
    text-align: center;
}
.languages-showcase h2 {
    font-size: 1.5rem;
    font-weight: 600;
    margin-bottom: var(--space-2);
    color: var(--text);
}
.languages-sub {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin: 0 auto 24px;
    max-width: 640px;
}
.languages-grid {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: center;
    max-width: 880px;
    margin: 0 auto;
}
.languages-grid li {
    margin: 0;
}
.languages-grid a {
    display: inline-block;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.875rem;
    text-decoration: none;
    transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.12s;
}
.languages-grid a:hover {
    border-color: var(--blue);
    color: var(--text);
    background: var(--surface-1);
    transform: translateY(-1px);
}

/* --- FAQ --- */
.faq {
    padding: 40px 0 80px;
}

.faq h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: var(--space-6);
    letter-spacing: -0.02em;
    text-align: center;
}

.faq-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.faq-item {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-1);
    transition: border-color 0.2s;
}

.faq-item[open] {
    border-color: var(--border-hover);
}

.faq-item summary {
    padding: 16px 20px;
    font-weight: 500;
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.faq-item summary::after {
    content: '+';
    font-size: 1.25rem;
    color: var(--text-muted);
    transition: transform 0.2s;
}

.faq-item[open] summary::after {
    content: '\2212';
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item p {
    padding: 0 20px 16px;
    color: var(--text-muted);
    font-size: 0.9375rem;
    line-height: 1.7;
}

/* --- Footer --- */
.site-footer {
    border-top: 1px solid var(--border);
    padding: var(--space-6);
}

.footer-inner {
    max-width: 960px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

/* ── Category columns ─────────────────────────────────────────────── */
.footer-cat-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 24px 20px;
    padding-bottom: var(--space-6);
    border-bottom: 1px solid var(--border);
}

.footer-cat-col h4 {
    font-size: 0.6875rem;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: var(--space-2);
}

.footer-cat-col a {
    display: block;
    color: var(--text-muted);
    font-size: 0.75rem;
    text-decoration: none;
    line-height: 1.9;
    transition: color 0.15s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.footer-cat-col a:hover { color: var(--text); }

/* ── Site nav columns (Tools / Legal & Info / Products) ───────────── */
.footer-nav-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px 40px;
    padding: 28px 0;
}

.footer-nav-col strong,
.footer-nav-col h4 {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 10px;
}

.footer-nav-col a {
    display: block;
    color: var(--text-muted);
    font-size: 0.8125rem;
    text-decoration: none;
    line-height: 2;
    transition: color 0.15s;
    white-space: nowrap;
}

.footer-nav-col a:hover { color: var(--text); }

.footer-copy {
    color: var(--text-muted);
    font-size: 0.75rem;
    margin-top: 6px;
}
.newsletter-pill-wrap {
    display: flex;
    justify-content: center;
    margin: var(--space-4) 0 var(--space-2);
}
.newsletter-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 0.8rem;
    text-decoration: none;
    transition: color 0.15s, border-color 0.15s;
}
.newsletter-pill:hover {
    color: var(--text);
    border-color: var(--accent);
}
.footer-newsletter {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: var(--space-6);
    align-items: start;
    padding: var(--space-5) 0;
    margin-top: var(--space-4);
    border-top: 1px solid var(--border);
}
.footer-newsletter-text strong {
    display: block;
    font-size: 0.95rem;
    color: var(--text);
    margin-bottom: 4px;
}
.footer-newsletter-text p {
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.45;
    margin: 0;
}
.footer-newsletter-form {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px;
    align-items: start;
}
.footer-newsletter-form input[type="email"] {
    grid-column: 1;
    padding: 10px 12px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font-size: 0.9rem;
    min-width: 0;
}
.footer-newsletter-form button {
    grid-column: 2;
    padding: 10px 16px;
    border-radius: 6px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: var(--accent-contrast, #fff);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}
.footer-newsletter-form button:disabled { opacity: 0.6; cursor: wait; }
.footer-newsletter-status {
    grid-column: 1 / -1;
    font-size: 0.8rem;
    min-height: 1.2em;
}
.footer-newsletter-status.ok { color: var(--success, #2ea043); }
.footer-newsletter-status.err { color: var(--danger, #d73a49); }
.footer-newsletter-fineprint {
    grid-column: 1 / -1;
    color: var(--text-muted);
    font-size: 0.7rem;
    opacity: 0.75;
    margin: 0;
}
@media (max-width: 720px) {
    .footer-newsletter { grid-template-columns: 1fr; gap: var(--space-4); }
}
/* N17: canonical brand sentence above the copyright on every page */
.footer-tagline {
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 500;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
    margin-top: 0;
    margin-bottom: 0;
}
/* R5: freshness stamp right below the copyright line */
.footer-freshness {
    color: var(--text-muted);
    opacity: 0.7;
    font-size: 0.7rem;
    margin: 4px 0 0;
}
.footer-freshness a {
    color: inherit;
    border-bottom: 1px dotted currentColor;
    text-decoration: none;
}
.footer-freshness a:hover { color: var(--accent, var(--blue)); }

/* Footer QR button, triggers on-demand QR modal */
.footer-qr-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.75rem;
    cursor: pointer;
    padding: 0;
    transition: color 0.15s;
    text-decoration: none;
    white-space: nowrap;
    display: inline;
    margin-left: var(--space-2);
}
.footer-qr-btn:hover {
    color: var(--text);
}

/* QR modal, on-demand QR code generation */
.qr-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    z-index: 1000;
    animation: qr-modal-fade 0.15s ease-out;
}
@keyframes qr-modal-fade {
    from { opacity: 0 }
    to { opacity: 1 }
}
.qr-modal[hidden] {
    display: none !important;
}
.qr-modal-backdrop {
    position: absolute;
    inset: 0;
}
.qr-modal-panel {
    position: relative;
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: var(--space-6);
    max-width: 320px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}
.qr-modal-close {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0;
    display: flex;
    transition: color 0.15s;
}
.qr-modal-close:hover {
    color: var(--text);
}
.qr-modal-title {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--text);
    margin: 0;
    text-align: center;
}
.qr-modal-desc {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin: 0;
    text-align: center;
}
.qr-modal-canvas {
    width: 200px;
    height: 200px;
    background: white;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto;
}
.qr-modal-url {
    font-size: 0.7rem;
    color: var(--text-muted);
    margin: 0;
    word-break: break-all;
    text-align: center;
    max-height: 40px;
    overflow: auto;
}

/* R2: pre-export scannability preflight modal */
.preflight-overlay {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
    z-index: 1000;
    animation: preflight-fade 0.15s ease-out;
}
@keyframes preflight-fade { from { opacity: 0 } to { opacity: 1 } }
.preflight-modal {
    background: var(--surface-1, #111214);
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 16px;
    max-width: 480px;
    width: 100%;
    padding: var(--space-6);
    box-shadow: 0 20px 48px rgba(0, 0, 0, 0.5);
}
.preflight-head {
    display: flex; align-items: center; gap: 14px;
    margin-bottom: 10px;
}
.preflight-grade {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    border-radius: 12px;
    font-size: 1.35rem; font-weight: 800;
    flex-shrink: 0;
}
.preflight-grade.grade-A { background: rgba(34,197,94,0.16); color: rgb(134,239,172); }
.preflight-grade.grade-B { background: rgba(132,204,22,0.16); color: rgb(217,249,157); }
.preflight-grade.grade-C { background: rgba(250,204,21,0.18); color: rgb(254,240,138); }
.preflight-grade.grade-D { background: rgba(249,115,22,0.20); color: rgb(254,215,170); }
.preflight-grade.grade-F { background: rgba(239,68,68,0.20); color: rgb(252,165,165); }
.preflight-title {
    margin: 0;
    font-size: 1.1rem;
    line-height: 1.3;
    color: var(--text, var(--text));
}
.preflight-lead {
    margin: 0 0 14px;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-muted, #aaa);
}
.preflight-risks {
    list-style: none;
    padding: 0;
    margin: 0 0 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.preflight-risk {
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 0.85rem;
    line-height: 1.45;
    border: 1px solid transparent;
}
.preflight-risk.warn {
    background: rgba(250,204,21,0.08);
    border-color: rgba(250,204,21,0.22);
    color: rgb(254,240,138);
}
.preflight-risk.fail {
    background: rgba(239,68,68,0.08);
    border-color: rgba(239,68,68,0.22);
    color: rgb(252,165,165);
}
.preflight-risk::before {
    display: inline-block;
    width: 1.1em;
    margin-inline-end: 6px;
    font-weight: 700;
}
.preflight-risk.warn::before { content: "⚠"; }
.preflight-risk.fail::before { content: "✗"; }
.preflight-actions {
    display: flex;
    gap: var(--space-2);
    justify-content: flex-end;
}
.preflight-btn {
    padding: 9px 18px;
    border-radius: 10px;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid var(--border, #2a2a2d);
    transition: background 0.15s, border-color 0.15s, transform 0.12s;
}
.preflight-btn:active { transform: translateY(1px); }
.preflight-btn-primary {
    background: linear-gradient(135deg, var(--blue), var(--purple));
    color: #08090a;
    border-color: transparent;
}
.preflight-btn-primary:hover { box-shadow: 0 2px 14px rgba(96,165,250,0.35); }
.preflight-btn-secondary {
    background: transparent;
    color: var(--text-muted, #aaa);
}
.preflight-btn-secondary:hover { color: var(--text, var(--text)); border-color: var(--text-muted, #666); }
body.preflight-open { overflow: hidden; }

/* V2: per-scenario scan-grade grid inside the preflight modal */
.preflight-scenarios {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
    margin: 0 0 14px;
}
@media (max-width: 420px) {
  .preflight-scenarios { grid-template-columns: 1fr; }
}
.preflight-scenario {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-rows: auto auto;
    gap: 2px 8px;
    padding: 8px 10px;
    border-radius: 8px;
    border: 1px solid var(--border, #2a2a2d);
    background: var(--surface-2, var(--surface-2));
    font-size: 0.78rem;
}
.preflight-scenario-glyph {
    grid-column: 1;
    grid-row: 1;
    font-size: 0.95rem;
}
.preflight-scenario-label {
    grid-column: 2;
    grid-row: 1;
    color: var(--text, var(--text));
    font-weight: 500;
}
.preflight-scenario-grade {
    grid-column: 3;
    grid-row: 1;
    padding: 1px 8px;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.8rem;
}
.preflight-scenario.grade-A .preflight-scenario-grade { background: rgba(34,197,94,0.18); color: rgb(134,239,172); }
.preflight-scenario.grade-B .preflight-scenario-grade { background: rgba(132,204,22,0.18); color: rgb(217,249,157); }
.preflight-scenario.grade-C .preflight-scenario-grade { background: rgba(250,204,21,0.22); color: rgb(254,240,138); }
.preflight-scenario.grade-D .preflight-scenario-grade { background: rgba(249,115,22,0.22); color: rgb(254,215,170); }
.preflight-scenario.grade-F .preflight-scenario-grade { background: rgba(239,68,68,0.22); color: rgb(252,165,165); }
.preflight-scenario-risk {
    grid-column: 1 / -1;
    grid-row: 2;
    color: var(--text-muted, #888);
    font-size: 0.72rem;
    opacity: 0.9;
}

/* V3: one-click auto-fix buttons */
.preflight-fixes {
    margin: 0 0 16px;
    padding: 10px 12px;
    border: 1px dashed var(--border, #2a2a2d);
    border-radius: 8px;
}
.preflight-fixes-label {
    margin: 0 0 8px;
    font-size: 0.78rem;
    color: var(--text-muted, #aaa);
}
.preflight-fixes-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.preflight-fix-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 7px 11px;
    border: 1px solid var(--border, #2a2a2d);
    border-radius: 7px;
    background: var(--surface-2, var(--surface-2));
    color: var(--text, var(--text));
    font-size: 0.78rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.preflight-fix-btn:hover {
    border-color: var(--accent, var(--blue));
    background: rgba(96,165,250,0.08);
}
.preflight-fix-btn:active { transform: translateY(1px); }

/* R7: compact discoverability hint.
   Lives above the mode toggle so it reads as site-level nav, not a
   Simple-mode footnote. Two escape hatches: Wizard, QR Lab. */
.mode-hint {
    text-align: center;
    font-size: 0.78rem;
    color: var(--text-muted, #888);
    /* Breathing room from the Pro CTA above, tight gap to the toggle below. */
    margin: 0 auto 14px;
    max-width: 720px;
    padding: 0 12px;
    line-height: 1.5;
}
.mode-hint a {
    color: var(--accent, var(--blue));
    text-decoration: none;
    border-bottom: 1px dashed transparent;
    transition: border-color 0.15s;
}
.mode-hint a:hover { border-bottom-color: currentColor; }
.mode-hint-sep { opacity: 0.4; margin: 0 4px; }
@media (max-width: 480px) {
  .mode-hint { font-size: 0.72rem; }
  .mode-hint-sep { display: block; height: 2px; overflow: hidden; visibility: hidden; }
}

/* N19.10: payload inspector. Collapsible, monospaced, shows the exact
   encoded string carried by the QR/barcode plus char/byte counts. Lives
   in the preview panel between the preview and the history list. */
.payload-inspector {
    margin-top: var(--space-4);
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 8px;
    background: var(--surface-1, #111);
    font-size: 0.85rem;
}
.payload-inspector summary {
    padding: 10px 14px;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    color: var(--text);
    font-weight: 500;
    list-style: none;
}
.payload-inspector summary::-webkit-details-marker { display: none; }
.payload-inspector summary::before {
    content: "▸";
    color: var(--text-muted, #888);
    margin-inline-end: 6px;
    transition: transform 0.15s;
}
.payload-inspector[open] summary::before {
    transform: rotate(90deg);
    display: inline-block;
}
.payload-meta {
    color: var(--text-muted, #888);
    font-size: 0.75rem;
    font-weight: 400;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.payload-body {
    padding: 0 14px 14px;
}
.payload-raw {
    margin: 0 0 10px;
    padding: 10px 12px;
    background: var(--surface-2, #1a1a1a);
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 6px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.8rem;
    line-height: 1.45;
    max-height: 240px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--text);
}
.payload-actions {
    display: flex;
    gap: var(--space-2);
}

/* N16: compliance-notes block for policy-sensitive landing pages.
   Renders below the SEO content, above the FAQ. Deliberately styled
   distinctly (amber/warning hue) so it reads as a decisive editorial
   judgment, not boilerplate. The "When not to use this" paragraph is
   even more prominent. */
.compliance-notes {
    margin: 32px 0;
    padding: 20px 24px;
    border-inline-start: 4px solid var(--amber);
    background: rgba(245, 158, 11, 0.05);
    border-radius: 8px;
}
.compliance-notes h2 {
    margin-top: 0;
    font-size: 1.15rem;
    color: var(--amber);
}
.compliance-notes h2::before {
    content: "⚠ ";
    margin-inline-end: 2px;
}
.compliance-notes h3 {
    margin: 16px 0 6px;
    font-size: 1rem;
    color: var(--text);
}
.compliance-list {
    padding-inline-start: var(--space-5);
    margin: 12px 0;
}
.compliance-list li {
    margin-bottom: 6px;
    line-height: 1.5;
}
.compliance-never {
    padding: 10px 14px;
    background: rgba(239, 68, 68, 0.08);
    border-inline-start: 3px solid var(--red);
    border-radius: 4px;
    font-weight: 500;
    margin: 0;
}

/* N14: jobs-first starter grid. Outcomes, not symbologies. Sits between
   the hero and the Simple/Advanced toggle. Each tile activates the
   matching type via JS and auto-flips to Advanced when needed. */
/* --- "What are you making?" showcase ---
   The job-starter grid is the first interactive surface a visitor sees.
   Enclosed in a subtle card so it reads as a self-contained picker, not
   a list floating in the hero. Generous margin-top from the subtitle
   gives the title breathing room; the card's own padding + border mark
   the container boundary. */
.job-starters {
    max-width: 820px;
    margin: 40px auto 16px;
    padding: 28px 28px 24px;
    background: linear-gradient(
        180deg,
        rgba(124, 92, 255, 0.04) 0%,
        rgba(96, 165, 250, 0.02) 100%
    );
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 20px;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset;
}
.job-starters-title {
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text, inherit);
    text-align: center;
    margin: 0 0 20px;
    /* Title now matches the conversational tone of the question;
       dropped the uppercase "section label" treatment that made it read
       as a minor hint instead of a genuine invitation. */
    letter-spacing: normal;
}
/* Persona filter chips, staged progressive disclosure. Row of pills
   directly under the showcase title; click to filter the tile grid by
   tagged persona. "All" is the default active state. */
.job-persona-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin: 0 0 18px;
}
.job-persona-chip {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-muted, var(--text-muted));
    background: transparent;
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.job-persona-chip:hover {
    color: var(--text, var(--text));
    border-color: var(--border-hover, rgba(255, 255, 255, 0.15));
}
.job-persona-chip.is-active {
    color: var(--bg, #08090a);
    background: var(--text, var(--text));
    border-color: var(--text, var(--text));
}
@media (max-width: 640px) {
    .job-persona-chips { margin-bottom: 14px; gap: var(--space-1); }
    .job-persona-chip { padding: 5px 10px; font-size: 0.72rem; }
}

.job-starters-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}
.job-starter {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 18px 10px;
    background: var(--surface-1, #111);
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 12px;
    color: var(--text, inherit);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 500;
    text-align: center;
    cursor: pointer;
    transition:
        border-color 0.15s,
        background 0.15s,
        transform 0.1s;
}
.job-starter:hover {
    border-color: var(--accent, var(--blue));
    background: var(--surface-2, #1a1a1a);
    transform: translateY(-1px);
}
.job-starter:active { transform: translateY(1px); }
.job-starter-ico { color: var(--accent, var(--blue)); }
.job-starter-label { line-height: 1.2; }
body.mode-scan .job-starters { display: none; }
body[data-qr-preselect] .job-starters { display: none; }
body[data-qr-preselect] .mode-hint { display: none; }
/* Wider tablets keep 3 columns (tiles grow in width), avoids squeezing
   labels onto 2 lines. Small screens drop to 2 columns so tiles stay
   tappable. */
@media (max-width: 640px) {
    .job-starters { padding: 20px 16px 18px; margin-top: 28px; border-radius: 16px; }
    .job-starters-title { font-size: 1rem; margin-bottom: var(--space-4); }
    .job-starters-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
    .job-starter { padding: 14px 8px; font-size: 0.78rem; }
}

/* N19.2: command palette. Fixed overlay, Cmd/Ctrl+K or "/" opens it, Escape
   or backdrop-click closes it. Keyboard-first; results fuzzy-match every
   type button in the DOM and jump to it + flip Advanced mode if needed. */
.cmd-palette {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 12vh;
}
.cmd-palette-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.cmd-palette-panel {
    position: relative;
    width: min(640px, 92vw);
    background: var(--surface-1, #111);
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 14px;
    box-shadow: 0 32px 80px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    animation: cmd-palette-in 140ms ease-out;
}
@keyframes cmd-palette-in {
    from { transform: translateY(-8px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}
.cmd-palette-input-wrap {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border, #2a2a2a);
}
.cmd-palette-icon { color: var(--text-muted, #888); flex-shrink: 0; }
.cmd-palette-input {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: 0;
    color: var(--text);
    font: inherit;
    font-size: 1rem;
    outline: none;
}
.cmd-palette-kbd {
    font-size: 0.72rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    background: var(--surface-2, #1a1a1a);
    padding: 2px 8px;
    border-radius: 4px;
    color: var(--text-muted, #888);
    border: 1px solid var(--border, #2a2a2a);
}
.cmd-palette-results {
    list-style: none;
    margin: 0;
    padding: 6px 0;
    max-height: 48vh;
    overflow-y: auto;
}
.cmd-palette-result {
    padding: 10px 18px;
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    border-inline-start: 2px solid transparent;
}
.cmd-palette-result:hover,
.cmd-palette-result.active {
    background: var(--surface-2, #1a1a1a);
    border-inline-start-color: var(--accent, var(--blue));
}
.cmd-palette-result-label { flex: 1; color: var(--text); }
.cmd-palette-result-cat {
    color: var(--text-muted, #888);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.cmd-palette-result-kbd {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    background: var(--surface-2, #1a1a1a);
    padding: 2px 8px;
    border-radius: 4px;
    color: var(--text-muted, #888);
    border: 1px solid var(--border, #2a2a2a);
}
.cmd-palette-empty {
    padding: 22px;
    text-align: center;
    color: var(--text-muted, #888);
    font-size: 0.9rem;
}
.cmd-palette-hint {
    padding: 10px 18px;
    color: var(--text-muted, #888);
    font-size: 0.75rem;
    border-top: 1px solid var(--border, #2a2a2a);
    text-align: center;
}
@media (max-width: 600px) {
    .cmd-palette { padding-top: 6vh; }
    .cmd-palette-kbd { display: none; }
    .cmd-palette-hint { display: none; }
}

/* Simple-mode escape hatch rendered directly below the 8-tile grid so the
   user finds Advanced at the point of friction (not back at the top). */
.simple-more-hint { display: none; }
body.mode-simple .simple-more-hint {
    display: block;
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-muted, #888);
    margin: 14px 0 0;
    line-height: 1.5;
}
.simple-more-hint-link {
    background: none;
    border: none;
    padding: 0;
    margin-inline-start: var(--space-1);
    color: var(--accent, var(--blue));
    font: inherit;
    cursor: pointer;
    border-bottom: 1px dashed transparent;
    transition: border-color 0.15s;
}
.simple-more-hint-link:hover { border-bottom-color: currentColor; }
@media (max-width: 480px) {
  .preflight-modal { padding: 18px; }
  .preflight-actions { flex-direction: column-reverse; }
  .preflight-btn { width: 100%; }
}

/* ── nav icon-only button ─────────────────────────────────────────── */
.nav-btn-icon {
    padding: 7px;
    gap: 0;
}

/* Drawer-only links are always hidden on desktop */
.nav-drawer-only { display: none; }

/* --- Toast --- */
.toast {
    position: fixed;
    bottom: 28px;
    inset-inline-start: 50%;
    transform: translateX(-50%);
    max-width: min(480px, calc(100vw - 32px));
    background: linear-gradient(135deg, rgba(30, 31, 34, 0.96), rgba(15, 16, 18, 0.96));
    color: var(--text);
    padding: 14px 20px 14px 46px;
    border-radius: 12px;
    font-size: 0.9rem;
    line-height: 1.4;
    font-weight: 500;
    border: 1px solid rgba(96, 165, 250, 0.3);
    z-index: 1000;
    animation: toastIn 0.35s cubic-bezier(0.16, 1, 0.3, 1);
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.5),
        0 4px 12px rgba(0, 0, 0, 0.3),
        0 0 0 1px rgba(255, 255, 255, 0.05) inset;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    /* Glyph (ℹ︎) as a leading accent; swaps via modifier classes for other types. */
    background-image:
        linear-gradient(135deg, rgba(30, 31, 34, 0.96), rgba(15, 16, 18, 0.96)),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2360a5fa' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='16' x2='12' y2='12'/><line x1='12' y1='8' x2='12.01' y2='8'/></svg>");
    background-repeat: no-repeat, no-repeat;
    background-position: 0 0, 14px center;
    background-size: 100% 100%, 20px 20px;
}
.toast.toast-success {
    border-color: rgba(52, 211, 153, 0.35);
    background-image:
        linear-gradient(135deg, rgba(30, 31, 34, 0.96), rgba(15, 16, 18, 0.96)),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2334d399' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6L9 17l-5-5'/></svg>");
}
.toast.toast-error {
    border-color: rgba(251, 113, 133, 0.45);
    background-image:
        linear-gradient(135deg, rgba(30, 31, 34, 0.96), rgba(15, 16, 18, 0.96)),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fb7185' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='12'/><line x1='12' y1='16' x2='12.01' y2='16'/></svg>");
}
.toast.toast-hiding {
    animation: toastOut 0.25s cubic-bezier(0.4, 0, 1, 1) forwards;
}
@keyframes toastIn {
    from { opacity: 0; transform: translateX(-50%) translateY(16px) scale(0.96); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes toastOut {
    from { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
    to   { opacity: 0; transform: translateX(-50%) translateY(8px) scale(0.98); }
}
@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; }
    .toast.toast-hiding { animation: none; opacity: 0; }
}

/* --- QR Scanner --- */
.scanner-section {
    padding: 0 0 48px;
    max-width: 500px;
    margin: 0 auto;
}

.scanner-layout {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.scanner-area {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    overflow: hidden;
    min-height: 280px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.scanner-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    padding: 40px 24px;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.scanner-btns {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    justify-content: center;
}

.scanner-video-wrap {
    position: relative;
    width: 100%;
}

.scanner-video-wrap video {
    display: block;
    width: 100%;
    height: auto;
}

.scanner-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.scanner-frame {
    position: relative;
    width: 220px;
    height: 220px;
    border-radius: 14px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45);
    overflow: hidden;
    isolation: isolate;
}
.scanner-frame::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 14px;
    pointer-events: none;
    background:
      linear-gradient(var(--blue), var(--blue)) top left / 28px 3px no-repeat,
      linear-gradient(var(--blue), var(--blue)) top left / 3px 28px no-repeat,
      linear-gradient(var(--blue), var(--blue)) top right / 28px 3px no-repeat,
      linear-gradient(var(--blue), var(--blue)) top right / 3px 28px no-repeat,
      linear-gradient(var(--blue), var(--blue)) bottom left / 28px 3px no-repeat,
      linear-gradient(var(--blue), var(--blue)) bottom left / 3px 28px no-repeat,
      linear-gradient(var(--blue), var(--blue)) bottom right / 28px 3px no-repeat,
      linear-gradient(var(--blue), var(--blue)) bottom right / 3px 28px no-repeat;
    animation: scanCornerPulse 2.4s ease-in-out infinite;
}
.scanner-frame::after {
    content: "";
    position: absolute;
    left: 6%;
    right: 6%;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg,
      rgba(96,165,250,0) 0%,
      rgba(96,165,250,0.9) 20%,
      rgba(52,211,153,1) 50%,
      rgba(96,165,250,0.9) 80%,
      rgba(96,165,250,0) 100%);
    box-shadow:
      0 0 8px rgba(96,165,250,0.9),
      0 0 22px rgba(52,211,153,0.55);
    animation: scanLaser 2.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
    pointer-events: none;
}

@keyframes scanLaser {
    0%   { top: 6%;  opacity: 0.2; }
    10%  { opacity: 1; }
    50%  { top: 94%; opacity: 1; }
    60%  { opacity: 0.2; }
    100% { top: 6%;  opacity: 0.2; }
}
@keyframes scanCornerPulse {
    0%, 100% { filter: drop-shadow(0 0 0 rgba(96,165,250,0)); opacity: 0.95; }
    50%      { filter: drop-shadow(0 0 6px rgba(96,165,250,0.6)); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .scanner-frame::after { animation: none; top: 50%; }
    .scanner-frame::before { animation: none; }
}

.scanner-stop-btn {
    position: absolute;
    bottom: var(--space-3);
    inset-inline-start: 50%;
    transform: translateX(-50%);
}

.scanner-video-actions {
    position: absolute;
    bottom: var(--space-3);
    inset-inline-start: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: var(--space-2);
}

#scanner-torch-btn.torch-on {
    background: var(--blue);
    color: var(--bg);
    border-color: var(--blue);
}

.scanner-drop-active {
    outline: 3px dashed var(--blue);
    outline-offset: -8px;
    background: rgba(96, 165, 250, 0.05);
}

.scanner-result {
    border: 1px solid var(--border-hover);
    border-radius: var(--radius);
    background: var(--surface-1);
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    animation: qrFadeIn 0.3s ease;
}

.scanner-result-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.scanner-result-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
/* When a non-QR format is active (Aztec, Data Matrix, PDF417, AAMVA,
   1D barcodes), QR-specific style controls (templates, my-styles, dot/eye
   shapes, scanability badge, frame, logo) don't apply, bwip-js renders
   monochrome with FG/BG only. Hiding them prevents user confusion where
   they'd toggle a setting and see no effect. The "Format note" panel
   appears in their place to explain. */
body.is-non-qr .qr-only-control { display: none !important; }
body.is-non-qr .scanability-badge { display: none !important; }

/* AAMVA driver-license form: 3-column responsive layout for short fields. */
.aamva-row-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 10px;
    margin-bottom: 10px;
}
@media (max-width: 560px) {
    .aamva-row-3 { grid-template-columns: 1fr; }
}
.aamva-disclaimer {
    border-inline-start: 3px solid var(--orange, var(--amber));
    background: rgba(245, 158, 11, 0.08);
    padding: 10px 12px;
    border-radius: 6px;
    margin-bottom: 14px;
    font-size: 0.8125rem;
    line-height: 1.5;
}

/* Structured License Preview card rendered when scanner decodes AAMVA. */
.aamva-preview {
    border: 1px solid var(--border-hover);
    border-radius: 12px;
    padding: var(--space-4);
    background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 18px;
    margin-top: var(--space-2);
}
.aamva-preview-header {
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    border-bottom: 1px solid var(--border);
    padding-bottom: 10px;
    margin-bottom: 6px;
}
.aamva-preview-header strong {
    font-size: 1.0625rem;
    letter-spacing: -0.01em;
}
.aamva-preview-header span {
    color: var(--text-muted);
    font-size: 0.8125rem;
}
.aamva-preview dt {
    color: var(--text-muted);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 2px;
}
.aamva-preview dd {
    margin: 0 0 4px 0;
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 500;
}
.aamva-preview-row {
    min-width: 0;
}

/* Format-info panel rendered when non-QR is active (HTML for it lives in
   index.html with id="non-qr-style-note"). */
body:not(.is-non-qr) #non-qr-style-note { display: none; }

/* Smart-parser structured cards: rendered when scanner detects a known
   schema (vCard, WIFI:, otpauth, BIP-21, geo:, etc.) instead of a raw
   payload blob. Same visual family as .aamva-preview. */
.scan-parsed-card {
    border: 1px solid var(--border-hover);
    border-radius: 12px;
    padding: 14px 16px;
    background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.scan-parsed-header {
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-2);
}
.scan-parsed-header strong {
    font-size: 1rem;
    color: var(--text);
}
.scan-parsed-warning {
    background: rgba(245, 158, 11, 0.12);
    border-inline-start: 3px solid var(--amber);
    padding: 10px 12px;
    border-radius: 6px;
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--text);
}
.scan-parsed-fields {
    display: grid;
    grid-template-columns: minmax(110px, 1fr) 2fr;
    gap: 4px 14px;
    margin: 0;
}
.scan-parsed-fields dt {
    color: var(--text-muted);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    align-self: center;
}
.scan-parsed-fields dd {
    margin: 0;
    color: var(--text);
    font-size: 0.875rem;
    word-break: break-word;
}
.scan-parsed-sensitive {
    -webkit-text-security: disc;
    text-security: disc;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.scan-parsed-note {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin: 0;
    line-height: 1.5;
}
.scan-parsed-actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}
.scan-parsed-raw {
    border-top: 1px solid var(--border);
    padding-top: 6px;
    font-size: 0.75rem;
}
.scan-parsed-raw summary {
    cursor: pointer;
    color: var(--text-muted);
}
.scan-parsed-raw pre {
    background: var(--surface-2);
    padding: 10px;
    border-radius: 6px;
    overflow-x: auto;
    font-size: 0.6875rem;
    color: var(--text-muted);
    white-space: pre-wrap;
    word-break: break-all;
    margin: 6px 0 0;
}

/* Detected-format chip displayed alongside the result label.
   E.g. "QR Code", "Aztec Code", "PDF417, Driver's License". */
.scanner-format-chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--blue);
    background: rgba(96, 165, 250, 0.12);
    border: 1px solid rgba(96, 165, 250, 0.3);
    border-radius: 999px;
    text-transform: none;
    letter-spacing: 0;
}

.scanner-result-content {
    font-size: 0.9375rem;
    color: var(--text);
    word-break: break-all;
    line-height: 1.6;
    padding: var(--space-3);
    background: var(--surface-2);
    border-radius: 8px;
}

.scanner-result-actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* --- Contrast Warning --- */
.contrast-warning {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 0.8125rem;
    line-height: 1.5;
    animation: qrFadeIn 0.3s ease;
}

.contrast-warning svg {
    flex-shrink: 0;
    margin-top: 1px;
}

.contrast-warning.warning-low {
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.3);
    color: var(--yellow);
}

.contrast-warning.warning-fail {
    background: rgba(239, 68, 68, 0.1);
    border: 1px solid rgba(239, 68, 68, 0.3);
    color: var(--red);
}

/* --- Crop Modal --- */
.crop-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
}

.crop-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
}

.crop-dialog {
    position: relative;
    background: var(--surface-1);
    border: 1px solid var(--border-hover);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    max-width: 500px;
    max-height: calc(100dvh - 48px);
    width: calc(100% - 32px);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    overflow-y: auto;
}

.crop-dialog h3 {
    font-size: 1.125rem;
    font-weight: 600;
}

.crop-hint {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.crop-container {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    background: var(--surface-2);
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
}

.crop-container img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 50dvh;
    object-fit: contain;
}

.crop-selection {
    position: absolute;
    border: 2px solid var(--blue);
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
    cursor: move;
}

.crop-handle {
    position: absolute;
    width: 20px;
    height: 20px;
    background: var(--blue);
    border: 2px solid var(--bg);
    border-radius: 50%;
}

.crop-handle-nw { top: -10px; inset-inline-start: -10px; cursor: nw-resize; }
.crop-handle-ne { top: -10px; inset-inline-end: -10px; cursor: ne-resize; }
.crop-handle-sw { bottom: -10px; inset-inline-start: -10px; cursor: sw-resize; }
.crop-handle-se { bottom: -10px; inset-inline-end: -10px; cursor: se-resize; }

.crop-actions {
    display: flex;
    gap: var(--space-2);
    justify-content: flex-end;
}

.crop-actions .btn {
    flex: 0;
}

/* --- Business Card Designer --- */
.btn-design-card {
    margin-top: var(--space-3);
    width: 100%;
    justify-content: center;
}

/* --- Custom modal (alert/confirm/prompt replacement) --- */
.custom-modal {
    position: fixed;
    inset: 0;
    z-index: 2200;
    display: flex;
    align-items: center;
    justify-content: center;
}

.custom-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
}

.custom-dialog {
    position: relative;
    background: var(--surface-1);
    border: 1px solid var(--border-hover);
    border-radius: var(--radius-lg);
    padding: 22px;
    width: min(440px, calc(100% - 32px));
    display: flex;
    flex-direction: column;
    gap: 14px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.custom-modal-title {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--text);
    margin: 0;
}

.custom-modal-message {
    font-size: 0.9375rem;
    color: var(--text-muted);
    margin: 0;
    line-height: 1.5;
}

.custom-modal-input {
    width: 100%;
    padding: 10px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    font-size: 0.9375rem;
    font-family: inherit;
}

.custom-modal-input:focus {
    outline: none;
    border-color: var(--blue);
}

.custom-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-1);
}

.card-modal {
    position: fixed;
    inset: 0;
    z-index: 2100;
    display: flex;
    align-items: center;
    justify-content: center;
}

.card-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.75);
    backdrop-filter: blur(6px);
}

.card-dialog {
    position: relative;
    background: var(--surface-1);
    border: 1px solid var(--border-hover);
    border-radius: var(--radius-lg);
    width: min(960px, calc(100% - 32px));
    max-height: calc(100dvh - 48px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.card-dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}

.card-dialog-header h3 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
}

.card-close-btn {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: var(--space-1);
    border-radius: 4px;
    display: flex;
    align-items: center;
    transition: background 0.15s, color 0.15s;
}

.card-close-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

.card-dialog-body {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: var(--space-5);
    padding: var(--space-5);
    overflow-y: auto;
    flex: 1;
}

.card-preview-wrap {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: center;
    justify-content: flex-start;
    position: sticky;
    top: 0;
    align-self: start;
}

.card-safe-area-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
}

.card-safe-area-overlay .csa-bleed {
    position: absolute;
    border: 2px dashed var(--red);
}

.card-safe-area-overlay .csa-safe {
    position: absolute;
    border: 2px dashed #10b981;
}

.info-lang-banner {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-inline-start: 3px solid var(--accent);
    padding: 10px 16px;
    border-radius: 8px;
    font-size: 0.875rem;
    color: var(--text-muted);
    margin: 0 0 24px;
}

.linkinbio-links {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 12px 12px;
    margin-top: var(--space-3);
}

.linkinbio-links legend {
    font-size: 12px;
    color: var(--text-muted);
    padding: 0 6px;
}

.linkinbio-row {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 6px;
    margin-bottom: 6px;
}

.linkinbio-row input {
    font-size: 13px;
    padding: 8px 10px;
}

.linkinbio-links details summary {
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    padding: 8px 0 4px;
    user-select: none;
}

.card-visibility-toggles {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 12px 10px;
    margin-top: 10px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 12px;
}

.card-visibility-toggles legend {
    font-size: 12px;
    color: var(--text-muted);
    padding: 0 6px;
}

.card-visibility-toggles .checkbox-label {
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
}

.card-modal.vcf-drop-active::after {
    content: "Drop .vcf to import";
    position: fixed;
    inset: 0;
    background: rgba(99, 102, 241, 0.15);
    color: #fff;
    font-size: 24px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 9999;
    border: 4px dashed #6366f1;
}

#card-canvas,
#card-canvas-back {
    width: 100%;
    max-width: 100%;
    height: auto;
    aspect-ratio: 7 / 4;
    background: #fff;
    border-radius: var(--radius);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}

#card-canvas-back {
    margin-top: var(--space-3);
}

.card-preview-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.card-controls {
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
}

/* Collapsible card sections via <details> */
.card-section {
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}

.card-section > summary {
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding: 10px 14px;
    cursor: pointer;
    user-select: none;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--surface-2);
}

.card-section > summary::-webkit-details-marker { display: none; }

.card-section > summary::before {
    content: "\25B8";
    display: inline-block;
    transition: transform 0.15s;
    font-size: 10px;
}

.card-section[open] > summary::before {
    transform: rotate(90deg);
}

.card-section > :not(summary) {
    padding: 12px 14px;
}

/* Preset thumbnail grid */
.card-preset-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    padding: 10px 14px;
}

.card-preset-btn {
    aspect-ratio: 7 / 4;
    background: var(--surface-2);
    background-size: cover;
    background-position: center;
    border: 2px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.15s, transform 0.12s;
    position: relative;
    overflow: hidden;
}

.card-preset-btn::after {
    content: attr(aria-label);
    position: absolute;
    bottom: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    padding: 2px 4px;
    background: rgba(0,0,0,0.65);
    color: #fff;
    font-size: 9px;
    text-align: center;
    line-height: 1.3;
    opacity: 0;
    transition: opacity 0.15s;
}

.card-preset-btn:hover::after,
.card-preset-btn.active::after {
    opacity: 1;
}

.card-preset-btn:hover {
    border-color: var(--border-hover);
    transform: scale(1.04);
}

.card-preset-btn.active {
    border-color: var(--blue);
    box-shadow: 0 0 0 1px var(--blue);
}

/* Color picker with hex input */
.card-color-picker-group {
    display: flex;
    align-items: center;
    gap: 6px;
}

.card-hex-input {
    width: 72px;
    padding: 4px 6px;
    font-size: 12px;
    font-family: ui-monospace, SFMono-Regular, monospace;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    text-transform: uppercase;
}

/* Color swatches row */
.card-color-swatches {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding-top: var(--space-2);
}

.card-swatch-btn {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 2px solid var(--border);
    cursor: pointer;
    transition: transform 0.1s, border-color 0.1s;
    padding: 0;
}

.card-swatch-btn:hover {
    transform: scale(1.2);
    border-color: var(--text);
}

.card-color-row,
.card-option-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}

.card-color-row label,
.card-option-row label {
    font-size: 0.8125rem;
    color: var(--text);
}

.card-color-row input[type="color"] {
    width: 40px;
    height: 28px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
    padding: 2px;
}

.card-option-row select {
    flex: 0 0 auto;
    min-width: 150px;
    padding: 8px 36px 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--surface-2);
    color: var(--text);
    font-size: 0.875rem;
    font-family: inherit;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    transition: border-color 0.2s, box-shadow 0.2s;
    outline: none;
}

.card-option-row select:focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.1);
}

.card-option-row select:hover {
    border-color: var(--border-hover);
}

.card-option-row input:not([type]),
.card-option-row input[type="text"],
.card-option-row input[type="number"] {
    flex: 0 0 auto;
    min-width: 150px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.875rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.card-option-row input:not([type]):focus,
.card-option-row input[type="text"]:focus,
.card-option-row input[type="number"]:focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.1);
}

.card-option-row input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--blue);
    cursor: pointer;
}

/* Stacked text input row: label on top, full-width input below. Used
   for tagline / QR caption where side-by-side is too cramped. The
   selector specificity here (`.card-modal .card-text-row > input[type]`
   = 0,2,1) already beats `.field-group input` (0,1,1), so no !important
   needed; the historical heavy-handedness here was defensive against an
   older overlap that no longer exists. */
.card-modal .card-text-row,
.card-text-row {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: 12px 0;
    margin: 0;
}
.card-modal .card-text-row + .card-text-row,
.card-text-row + .card-text-row {
    border-top: 1px dashed var(--border);
}
.card-modal .card-text-row > label,
.card-text-row > label {
    font-size: 0.75rem;
    color: var(--text-secondary);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}
/* Must match both input[type="text"] and input:not([type]) because the HTML
   minifier in cf-deploy.py strips the default type="text" attribute in dist/,
   leaving the production input without a type. Bare [type="text"] selectors
   would silently stop applying. */
.card-modal .card-text-row > input[type="text"],
.card-modal .card-text-row > input:not([type]),
.card-text-row > input[type="text"],
.card-text-row > input:not([type]) {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.9375rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
    margin: 0;
}
.card-modal .card-text-row > input[type="text"]:hover,
.card-modal .card-text-row > input:not([type]):hover,
.card-text-row > input[type="text"]:hover,
.card-text-row > input:not([type]):hover {
    background: var(--surface-3);
}
.card-modal .card-text-row > input[type="text"]::placeholder,
.card-modal .card-text-row > input:not([type])::placeholder,
.card-text-row > input[type="text"]::placeholder,
.card-text-row > input:not([type])::placeholder {
    color: var(--text-muted);
    opacity: 0.55;
    font-style: italic;
}
.card-modal .card-text-row > input[type="text"]:focus,
.card-modal .card-text-row > input:not([type]):focus,
.card-text-row > input[type="text"]:focus,
.card-text-row > input:not([type]):focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.18);
    background: var(--surface-3);
}

/* Print services modal */
.print-services-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6);
}
.print-services-modal {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    max-width: 560px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    padding: var(--space-6);
}
.print-services-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-2);
}
.print-services-header h3 {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--text);
}
.print-services-close {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: var(--space-1);
    border-radius: 6px;
    transition: color 0.15s;
}
.print-services-close:hover { color: var(--text); }
.print-services-sub {
    font-size: 0.8125rem;
    color: var(--text-muted);
    line-height: 1.5;
    margin-bottom: var(--space-4);
}
.print-services-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    margin-bottom: 14px;
}
.print-service-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    text-decoration: none;
    color: var(--text);
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.print-service-card:hover {
    border-color: var(--blue);
    background: var(--surface-3);
    transform: translateY(-1px);
}
.print-service-name {
    font-weight: 700;
    font-size: 0.9375rem;
}
.print-service-tag {
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--blue);
    font-weight: 600;
}
.print-service-price {
    font-size: 0.8125rem;
    color: var(--text-muted);
}
.print-services-note {
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.4;
    padding: 10px 12px;
    background: var(--surface-2);
    border-radius: 8px;
    border: 1px dashed var(--border);
}
@media (max-width: 480px) {
    .print-services-grid { grid-template-columns: 1fr; }
}

/* "Show more layouts" expander inside preset grid details */
.card-preset-more {
    grid-column: 1 / -1;
    display: flex;
    justify-content: center;
    padding: 4px 0 0;
}
.card-preset-more-btn {
    background: transparent;
    border: 1px dashed var(--border-hover);
    color: var(--text-muted);
    padding: 8px 14px;
    font-size: 0.75rem;
    border-radius: 6px;
    cursor: pointer;
    font-family: inherit;
    transition: border-color 0.15s, color 0.15s;
}
.card-preset-more-btn:hover {
    border-color: var(--blue);
    color: var(--text);
}

/* --- Section label row with right-aligned action (templates etc.) --- */
.section-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: 10px;
}
.section-label-row .section-label {
    margin-bottom: 0;
}
.section-label-row .btn-sm {
    padding: 4px 10px;
    font-size: 0.75rem;
    gap: var(--space-1);
}

/* --- Card dialog header: kebab menu + close button --- */
.card-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}
.overflow-menu {
    position: relative;
}
.overflow-menu-btn {
    width: 36px;
    height: 36px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
}
.overflow-menu-btn:hover,
.overflow-menu-btn[aria-expanded="true"] {
    background: var(--surface-2);
}
.overflow-menu-list {
    position: absolute;
    top: calc(100% + 4px);
    inset-inline-end: 0;
    min-width: 200px;
    padding: 6px;
    background: var(--surface-1);
    border: 1px solid var(--border-hover);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    display: none;
    flex-direction: column;
    gap: 2px;
    z-index: 100;
}
.overflow-menu-list.open {
    display: flex;
}
.overflow-menu-list button,
.overflow-menu-list .overflow-menu-file {
    display: block;
    width: 100%;
    padding: 10px 14px;
    border: none;
    background: transparent;
    color: var(--text);
    text-align: start;
    font: inherit;
    font-size: 0.875rem;
    cursor: pointer;
    border-radius: 6px;
    transition: background 0.12s;
}
.overflow-menu-list button:hover,
.overflow-menu-list button:focus-visible,
.overflow-menu-list .overflow-menu-file:hover,
.overflow-menu-list .overflow-menu-file:focus-visible {
    background: var(--surface-2);
    outline: none;
}

/* Card dialog footer: make Cancel left, downloads right, with a flexible
   spacer so buttons never overflow on narrow screens. */
.card-dialog-footer {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}
.card-dialog-footer-spacer {
    flex: 1 1 auto;
    min-width: 0;
}
@media (max-width: 560px) {
    .card-dialog-footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }
    .card-dialog-footer-spacer {
        display: none;
    }
    .card-dialog-footer .btn {
        width: 100%;
    }
}

/* --- Scannability validator badge --- */
.scanability-badge {
    position: absolute;
    bottom: -18px;
    inset-inline-end: var(--space-3);
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    backdrop-filter: blur(8px);
    pointer-events: auto;
    cursor: help;
    display: none;
    z-index: 2;
}
.scanability-badge.ok {
    display: inline-block;
    background: rgba(34, 197, 94, 0.18);
    color: #4ade80;
    border: 1px solid rgba(34, 197, 94, 0.4);
}
.scanability-badge.fail {
    display: inline-block;
    background: rgba(239, 68, 68, 0.18);
    color: #fca5a5;
    border: 1px solid rgba(239, 68, 68, 0.5);
}
.qr-preview {
    position: relative;
}

/* --- Info pages (privacy / terms / security / about / blog / vs) --- */
.info-page {
    max-width: 760px;
    margin: 0 auto;
    padding: 80px 24px 96px;
}
.info-article h1 {
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 800;
    letter-spacing: -0.035em;
    margin: 0 0 12px;
    line-height: 1.1;
    background: linear-gradient(135deg, var(--text) 0%, var(--text-muted) 120%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.info-lead {
    font-size: 1.25rem;
    color: var(--text-muted);
    margin: 0 0 48px;
    line-height: 1.55;
    font-weight: 400;
    max-width: 640px;
}
.info-article h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 48px 0 16px;
    letter-spacing: -0.018em;
    color: var(--text);
}
.info-article h3 {
    font-size: 1.15rem;
    font-weight: 600;
    margin: 32px 0 12px;
    letter-spacing: -0.01em;
    color: var(--text);
}
.info-article p {
    line-height: 1.75;
    margin: 0 0 20px;
    color: var(--text);
    font-size: 1.05rem;
}
.info-article a {
    color: var(--blue, var(--blue));
    text-decoration: underline;
    text-decoration-color: rgba(96, 165, 250, 0.35);
    text-underline-offset: 3px;
    transition: text-decoration-color 0.15s;
}
.info-article a:hover {
    text-decoration-color: currentColor;
}
/* Anchors styled as buttons inside info-article need to override the
   blue link color, .btn-primary has a blue background, so the default
   info-article a rule renders text blue-on-blue (invisible). */
.info-article a.btn-primary {
    color: #08090a;
    text-decoration: none;
}
.info-article a.btn-secondary,
.info-article a.btn {
    color: var(--text);
    text-decoration: none;
}
.info-article code {
    background: var(--surface-2);
    padding: 2px 7px;
    border-radius: 5px;
    font-size: 0.9em;
    border: 1px solid var(--border);
    font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.info-article strong {
    color: var(--text);
    font-weight: 600;
}
.info-meta {
    margin-top: var(--space-16);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.875rem;
    font-style: italic;
}
.info-article pre {
    background: var(--surface-2);
    border: 1px solid var(--border);
    padding: 16px 20px;
    border-radius: 10px;
    overflow-x: auto;
    font-size: 0.9em;
    line-height: 1.55;
    margin: 24px 0;
}
.info-article pre code {
    background: transparent;
    padding: 0;
    border: none;
}
.info-article ul, .info-article ol {
    line-height: 1.75;
    margin: 0 0 24px;
    padding-inline-start: 28px;
    font-size: 1.05rem;
}
.info-article li {
    margin-bottom: 10px;
}
.info-article ul li::marker {
    color: var(--blue, var(--blue));
}
.info-article .vs-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 24px 0 32px;
    font-size: 0.95em;
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}
.info-article .vs-table th,
.info-article .vs-table td {
    border-bottom: 1px solid var(--border);
    padding: 12px 16px;
    text-align: start;
    vertical-align: top;
}
.info-article .vs-table tr:last-child th,
.info-article .vs-table tr:last-child td {
    border-bottom: none;
}
.info-article .vs-table th {
    background: var(--surface-2);
    font-weight: 600;
    color: var(--text);
}
.info-article .vs-table td:first-child {
    font-weight: 500;
    color: var(--text);
}
.info-article .vs-table td:nth-child(2) {
    color: #4ade80;
}
.info-article .blog-index {
    list-style: none;
    padding-inline-start: 0;
    margin-top: var(--space-8);
}
.info-article .blog-index li {
    padding: 0;
    margin-bottom: var(--space-5);
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    transition: border-color 0.15s, transform 0.15s;
}
.info-article .blog-index li::marker {
    display: none;
    content: none;
}
.info-article .blog-index li:hover {
    border-color: var(--blue, var(--blue));
    transform: translateY(-2px);
}
.info-article .blog-index li a {
    display: block;
    padding: 20px 24px;
    text-decoration: none;
    color: var(--text);
}
.info-article .blog-index li a strong {
    display: block;
    font-size: 1.2rem;
    font-weight: 700;
    margin-bottom: 6px;
    color: var(--text);
}

/* Blog post body tweaks */
.info-article blockquote {
    border-inline-start: 3px solid var(--blue, var(--blue));
    padding: 8px 20px;
    margin: 24px 0;
    color: var(--text-muted);
    font-style: italic;
}
.info-article hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: 48px 0;
}
.footer-nav {
    display: flex;
    gap: var(--space-4);
    flex-wrap: wrap;
}
.footer-nav a {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.875rem;
}
.footer-nav a:hover {
    color: var(--text);
}

.card-dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: 16px 20px;
    border-top: 1px solid var(--border);
}

@media (max-width: 720px) {
    .card-dialog-body {
        grid-template-columns: 1fr;
    }
    .card-preview-wrap {
        position: sticky;
        top: 0;
        z-index: 5;
        background: var(--surface-1);
        padding: 10px 0;
        border-bottom: 1px solid var(--border);
    }
    #card-canvas, #card-canvas-back {
        max-height: 180px;
        width: auto;
        margin: 0 auto;
    }
    .card-preview-hint { display: none; }
    .card-controls {
        gap: var(--space-2);
        padding-bottom: 70px;
    }
    .card-dialog-footer {
        position: sticky;
        bottom: 0;
        background: var(--surface-1);
        border-top: 1px solid var(--border);
        z-index: 5;
    }
    .card-preset-grid {
        grid-template-columns: repeat(3, 1fr) !important;
    }
    .card-section > :not(summary) {
        padding: 8px 10px;
    }
}

/* --- Landing Page SEO Content --- */
.seo-content {
    max-width: 720px;
    margin: 48px auto;
    padding: 0 20px;
}

.seo-content h2 {
    font-size: 1.375rem;
    font-weight: 700;
    margin: 32px 0 12px;
    letter-spacing: -0.01em;
}

.seo-content h2:first-child {
    margin-top: 0;
}

.seo-content p {
    color: var(--text-secondary);
    font-size: 0.9375rem;
    line-height: 1.7;
    margin: 0 0 12px;
}

.seo-content a {
    color: var(--blue);
    text-decoration: none;
}

.seo-content a:hover {
    text-decoration: underline;
}

.seo-content ul, .seo-content ol {
    color: var(--text-secondary);
    font-size: 0.9375rem;
    line-height: 1.7;
    padding-inline-start: var(--space-6);
    margin: 0 0 16px;
}

.seo-content li {
    margin-bottom: 6px;
}

/* --- All QR Types Link Grid --- */
.type-links {
    max-width: 720px;
    margin: 32px auto 48px;
    padding: 0 20px;
}

.type-links h2 {
    font-size: 1.25rem;
    font-weight: 700;
    margin-bottom: var(--space-4);
}

.type-links-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.type-links-grid a {
    display: inline-block;
    padding: 6px 14px;
    background: var(--surface-2);
    border: 1px solid var(--surface-3);
    border-radius: 8px;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}

.type-links-grid a:hover {
    background: var(--surface-3);
    color: var(--text);
}

.type-link-current {
    display: inline-block;
    padding: 6px 14px;
    background: var(--blue);
    border-radius: 8px;
    color: var(--bg);
    font-size: 0.8125rem;
    font-weight: 600;
}

/* --- Field Validation --- */
.field-group input.input-warning,
.field-group textarea.input-warning,
.field-group select.input-warning,
.input-warning {
    border-color: var(--amber);
    box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.3);
}

.field-validation {
    display: block;
    color: var(--amber);
    font-size: 0.75rem;
    margin-top: var(--space-1);
    line-height: 1.4;
}

/* --- Language Switcher --- */
.lang-switcher {
    appearance: none;
    -webkit-appearance: none;
    background: var(--surface-2);
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 6px 28px 6px 10px;
    font-size: 0.8125rem;
    font-family: inherit;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23a3a3a3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
    transition: border-color 0.2s;
}

.lang-switcher:hover {
    border-color: var(--border-hover);
    color: var(--text);
}

.lang-switcher:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

.lang-switcher option {
    background: var(--surface-2);
    color: var(--text);
}

/* --- Print Styles --- */
@media print {
    body {
        background: #fff;
        color: #000;
    }

    /* Strip colorblind simulation filters when printing, printers
       reproduce true colors, and we don't want to bake a sim into output. */
    .qr-preview.cb-protanopia .qr-canvas-wrap,
    .qr-preview.cb-deuteranopia .qr-canvas-wrap,
    .qr-preview.cb-tritanopia .qr-canvas-wrap {
        filter: none !important;
    }

    .bg-orbs, .site-header, .hero, .mode-toggle, .controls-panel,
    .quick-actions, .history-panel, .sign-cta, .how-it-works, .faq,
    .site-footer, .scanner-section, .toast, .skip-link {
        display: none !important;
    }

    .generator-layout {
        display: block;
    }

    .preview-panel {
        position: static;
    }

    .qr-preview {
        border: none;
        background: none;
        padding: 0;
        display: flex;
        justify-content: center;
        min-height: auto;
    }

    .qr-canvas-wrap {
        box-shadow: none;
        padding: 0;
    }

    /* Force the QR canvas to its rendered size for crisp print output. */
    #qr-canvas {
        max-width: none;
        width: 100%;
        height: auto;
    }

    main {
        max-width: none;
        padding: var(--space-10);
    }

    @page {
        margin: 12mm;
    }
}

/* --- Coarse-pointer touch target sizes (WCAG 2.5.8) --- */
@media (pointer: coarse) {
    .btn-sm,
    .nav-btn,
    .lang-switcher,
    .panel-tab,
    .cat-btn,
    .type-btn,
    .template-btn,
    .history-item,
    .batch-preview-item,
    .logo-preset-btn,
    .card-preset-btn {
        min-height: 44px;
        min-width: 44px;
    }
}

/* --- Reduced motion: respect user OS preference (WCAG 2.3.3) --- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .bg-orbs {
        display: none !important;
    }
}

/* --- Responsive --- */
@media (max-width: 768px) {
    .generator-layout {
        grid-template-columns: 1fr;
    }

    .preview-panel {
        position: static;
    }

    /* On single-column layouts the 24px page gutter is wasted horizontal
       real estate — every input and the QR preview want every pixel.
       Tighten the page edges and the preview's internal padding so the
       app reads edge-to-edge on phones and small tablets. */
    main { padding: 0 12px; }
    .site-header { padding: 12px 12px; }
    .qr-preview { padding: var(--space-4); }

    .hero { padding: 32px 0 20px; }

    /* Hamburger appears, nav becomes a slide-down drawer */
    .nav-hamburger {
        display: inline-flex;
    }

    .header-nav {
        position: fixed;
        top: var(--space-16);
        inset-inline-end: var(--space-3);
        inset-inline-start: var(--space-3);
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
        padding: 14px;
        background: var(--surface-1);
        border: 1px solid var(--border-hover);
        border-radius: var(--radius-lg);
        box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
        z-index: 1550;
        transform: translateY(-12px);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: transform 0.2s, opacity 0.2s, visibility 0s linear 0.2s;
    }

    body.nav-open .header-nav {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transition: transform 0.2s, opacity 0.2s;
    }
    /* Backdrop dims the page when the menu is open, visual confirmation
       that the click registered, plus a click-target to dismiss. */
    body.nav-open::after {
        content: "";
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.45);
        z-index: 1540;
        pointer-events: none;
        animation: navFadeIn 0.2s ease-out;
    }
    @keyframes navFadeIn {
        from { opacity: 0; }
        to   { opacity: 1; }
    }

    body.nav-open {
        overflow: hidden;
    }

    .header-nav .nav-link,
    .header-nav .nav-btn {
        padding: 12px 14px;
        width: 100%;
        justify-content: flex-start;
        border-radius: var(--radius);
        font-size: 0.9375rem;
    }

    .header-nav .nav-btn span,
    .header-nav .nav-link span {
        font-size: 0.9375rem;
    }

    .header-nav .lang-switcher {
        width: 100%;
        padding: 12px 32px 12px 14px;
        font-size: 0.9375rem;
    }

    .steps {
        grid-template-columns: 1fr;
    }

    .sign-cta-body {
        flex-direction: column;
        text-align: center;
    }

    .sign-cta-badge { text-align: center; }
    .sign-cta-content { align-items: center; }
    .sign-cta p { max-width: none; }
    .sign-cta .btn-gradient { align-self: center; }
    .sign-features { align-items: center; }

    .sign-cta-visual { display: none; }

    .footer-cat-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .footer-nav-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 16px 24px;
    }

    .type-selector {
        gap: var(--space-1);
    }

    .type-btn {
        padding: 6px 10px;
        font-size: 0.8125rem;
    }

    .template-grid {
        grid-template-columns: repeat(5, 1fr);
    }

    .history-list {
        grid-template-columns: repeat(4, 1fr);
    }

    /* Desktop header: hide nav-links (except sign) and collapse btn text */
    .header-nav .nav-link:not(.sign-link) {
        display: none;
    }

    .nav-btn {
        padding: 6px 8px;
        font-size: 0;
    }

    .nav-btn svg {
        width: 18px;
        height: 18px;
    }

    /* Open drawer: show everything at full size */
    body.nav-open .header-nav .nav-link,
    body.nav-open .header-nav .nav-drawer-only {
        display: flex;
    }

    body.nav-open .header-nav .nav-btn {
        font-size: 0.9375rem;
        padding: 12px 14px;
    }

    body.nav-open .header-nav .nav-btn-icon {
        padding: 12px 14px;
        gap: var(--space-2);
    }
}

@media (max-width: 480px) {
    main { padding: 0 8px; }
    .site-header { padding: 10px 8px; }

    .hero h1 { font-size: 1.5rem; }
    .hero-subtitle { font-size: 0.9375rem; }

    .qr-preview { padding: var(--space-6); min-height: 280px; }

    .template-grid {
        grid-template-columns: repeat(5, 1fr);
        gap: var(--space-1);
    }

    .type-categories {
        flex-wrap: wrap;
    }

    .footer-cat-grid {
        grid-template-columns: 1fr 1fr;
    }

    .footer-nav-grid {
        grid-template-columns: 1fr 1fr;
    }
}

/* ──────────────────────────────────────────────────────────────────────── */
/* /contact/ form, the one form on the site that posts to a backend.     */

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin: 24px 0 32px;
    max-width: 640px;
}

.contact-form .form-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.contact-form label {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text);
}

.contact-form .form-optional {
    font-weight: 400;
    color: var(--text-muted);
    font-size: 0.85em;
}

.contact-form .form-required {
    color: var(--pink);
    font-weight: 700;
}

/* input:not([type]) selectors exist because our HTML minifier strips the
   default type="text" attribute, `<input type="text">` ships as `<input>`,
   so a [type="text"] selector alone would miss every text input in prod. */
.contact-form input:not([type]),
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form input[type="file"],
.contact-form textarea {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
    color: var(--text);
    font: inherit;
    font-size: 0.95rem;
    transition: border-color 0.15s;
}

.contact-form input:not([type]):focus,
.contact-form input[type="text"]:focus,
.contact-form input[type="email"]:focus,
.contact-form input[type="file"]:focus,
.contact-form textarea:focus {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
    border-color: var(--blue);
}

.contact-form input[type="file"] {
    padding: 8px 10px;
    cursor: pointer;
}

.contact-form input[type="file"]::file-selector-button {
    background: var(--surface-3, #2a2d34);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    padding: 4px 12px;
    margin-inline-end: 10px;
    cursor: pointer;
    font: inherit;
    font-size: 0.85rem;
}

.contact-form textarea {
    resize: vertical;
    min-height: 140px;
    font-family: inherit;
}

.contact-form .form-row-fieldset {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px 16px;
    margin: 0;
}

.contact-form .form-row-fieldset legend {
    padding: 0 8px;
    font-weight: 600;
    color: var(--text);
}

.contact-form .radio-option,
.contact-form .checkbox-option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-weight: 400;
    padding: 6px 0;
    cursor: pointer;
    line-height: 1.5;
}

.contact-form .radio-option input,
.contact-form .checkbox-option input {
    margin-top: 3px;
    flex-shrink: 0;
    /* Brand the checked state and guarantee a visible outline on dark. */
    accent-color: var(--blue);
    width: 16px;
    height: 16px;
}

/* Chrome under `color-scheme: dark` paints the unchecked checkbox as a
   dark outline on dark surface, it was invisible until hover. Replace
   the native rendering with a hand-drawn box that always shows a 1px
   border against --surface-2, then brand-fill + SVG check on :checked. */
.contact-form .checkbox-option input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    margin-top: 2px;
    width: 18px;
    height: 18px;
    border: 1px solid var(--text-muted);
    border-radius: 4px;
    background: var(--bg);
    cursor: pointer;
    position: relative;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.contact-form .checkbox-option input[type="checkbox"]:hover {
    border-color: var(--text);
}

.contact-form .checkbox-option input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

.contact-form .checkbox-option input[type="checkbox"]:checked {
    background: var(--blue);
    border-color: var(--blue);
}

.contact-form .checkbox-option input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    inset-inline-start: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.contact-form .checkbox-option {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    /* Reset the form-row column flex so checkbox sits beside its label. */
    flex-direction: row;
}

.contact-form .photo-previews {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-top: var(--space-2);
}

.contact-form .photo-preview {
    position: relative;
    width: 88px;
    height: 88px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
}

.contact-form .photo-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.contact-form .photo-preview-remove {
    position: absolute;
    top: var(--space-1);
    inset-inline-end: var(--space-1);
    width: 22px;
    height: 22px;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.contact-form .form-hint {
    font-size: 0.82rem;
    color: var(--text-muted);
    text-align: end;
}

.contact-form .form-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.contact-form .form-feedback {
    font-size: 0.9rem;
    text-align: start;
}

.contact-form .form-feedback-success {
    color: var(--green);
}

.contact-form .form-feedback-error {
    color: var(--pink);
}

.contact-form .btn-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: contact-spin 0.7s linear infinite;
}

.contact-form .btn:disabled {
    opacity: 0.65;
    cursor: not-allowed;
}

@keyframes contact-spin {
    to { transform: rotate(360deg); }
}

.info-meta-box {
    background: rgba(96, 165, 250, 0.08);
    border: 1px solid rgba(96, 165, 250, 0.22);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin: 0 0 24px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text);
}

.info-meta-box strong {
    color: var(--blue);
}


/* S9, Site search modal (Pagefind UI). Mirrors the .cmd-palette look
   so the two surfaces feel like one product. */
.site-search-modal {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 10vh;
}
.site-search-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.site-search-panel {
    position: relative;
    width: min(720px, 94vw);
    max-height: 80vh;
    overflow: auto;
    background: var(--surface-1, #111);
    border: 1px solid var(--border, #2a2a2a);
    border-radius: 14px;
    box-shadow: 0 32px 80px rgba(0, 0, 0, 0.5);
    animation: cmd-palette-in 140ms ease-out;
    padding: var(--space-5);
}
.site-search-close {
    position: absolute;
    top: 10px;
    inset-inline-end: 10px;
    background: transparent;
    border: none;
    color: var(--text-muted, #888);
    cursor: pointer;
    padding: var(--space-2);
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}
.site-search-close:hover { background: var(--surface-2, #1a1a1a); color: var(--text); }
body.site-search-open { overflow: hidden; }
/* Scope Pagefind UI to the site's color palette. */
.pagefind-ui {
    --pagefind-ui-primary: var(--blue, var(--blue));
    --pagefind-ui-text: var(--text, #eee);
    --pagefind-ui-background: var(--surface-1, #111);
    --pagefind-ui-border: var(--border, #2a2a2a);
    --pagefind-ui-border-width: 1px;
    --pagefind-ui-border-radius: 8px;
    --pagefind-ui-image-border-radius: 8px;
    --pagefind-ui-font: inherit;
}
@media (max-width: 640px) {
    .site-search-modal { padding-top: 4vh; }
    .site-search-panel { padding: 14px; }
}

/* --- 2026-04-23 merit-first copy additions --- */

/* Hero subtitle inline link (to RoamingPigs exposé), secondary CTA
   pill that matches the upper hero-pill's visual language without
   competing with it for the primary-CTA slot. */
.hero-subtitle-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    margin-inline-start: var(--space-1);
    padding: 3px 10px 3px 10px;
    background: rgba(96, 165, 250, 0.10);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.25));
    border-radius: 999px;
    color: var(--blue, var(--blue));
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.hero-subtitle-link:hover {
    border-color: var(--blue, var(--blue));
    background: rgba(96, 165, 250, 0.18);
    color: var(--text, var(--surface-tile-hover));
    text-decoration: none;
}
@media (max-width: 640px) {
    .hero-subtitle-link {
        margin-inline-start: 0;
        margin-top: var(--space-2);
    }
}

/* Trust microcopy under Download buttons (dark theme; matches project vars) */
.export-trust {
    margin: 14px 0 4px;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text, var(--text));
}
.export-trust-sub {
    margin: 0 0 8px;
    font-size: 0.85rem;
    color: var(--text-muted, var(--text-muted));
    line-height: 1.5;
}

/* Industry-context section removed 2026-04-24: the hero subhead already
   carries the mechanism explanation + the outbound RoamingPigs link, so
   a dedicated section duplicates the message. If we ever bring it back,
   the previous rules lived here, reinstate from git history. */

/* =============================================================
   Mobile UX overhaul (2026-04-25)
   Peek-preview header, bottom-sheet preview, sticky download CTA,
   keyboard-aware layout, tap-target normalization.
   All rules scoped to <=768px so desktop is untouched.
   ============================================================= */

/* Hidden by default, only the mobile breakpoint shows them. The
   .preview-close (X button on the bottom-sheet) is also default-hidden
   here so a leftover body.preview-open class from a mobile-width
   session doesn't keep it floating on top of the desktop layout when
   the user resizes the window. */
.mobile-peek,
.mobile-cta,
.preview-close {
    display: none;
}

@media (max-width: 768px) {
    /* Hamburger sits above the peek bar so it stays tappable when the peek
       bar pins at viewport top during scroll. We deliberately DO NOT add
       z-index to .site-header itself, that creates a stacking context
       which traps the .header-nav drawer below the body-level nav
       backdrop and makes menu items unclickable. */
    .site-header { background: var(--bg); }
    .nav-hamburger {
        position: relative;
        z-index: 50;
    }
    /* --- Peek-preview sticky header --- */
    .mobile-peek {
        display: flex;
        position: sticky;
        top: 0;
        z-index: 40;
        align-items: center;
        gap: var(--space-3);
        width: 100%;
        padding: 10px 14px;
        padding-top: max(10px, env(safe-area-inset-top));
        background: var(--bg, #0a0a0a);
        border: 0;
        border-bottom: 1px solid var(--border, #2a2a2a);
        color: var(--text, var(--text));
        text-align: start;
        cursor: pointer;
        font: inherit;
        min-height: 64px;
        transition: min-height 0.18s ease, padding 0.18s ease;
    }
    .mobile-peek:focus-visible {
        outline: 2px solid var(--blue);
        outline-offset: -2px;
    }
    .mobile-peek-thumb {
        position: relative;
        flex: 0 0 auto;
        width: 44px;
        height: 44px;
        border-radius: 8px;
        background: #fff;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
    }
    .mobile-peek-thumb-placeholder {
        color: #1a1a1a;
        opacity: 0.7;
    }
    .mobile-peek-thumb-img {
        width: 100%;
        height: 100%;
        object-fit: contain;
        display: none;
    }
    .mobile-peek.is-ready .mobile-peek-thumb-img {
        display: block;
    }
    .mobile-peek.is-ready .mobile-peek-thumb-placeholder {
        display: none;
    }
    .mobile-peek-text {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: 2px;
    }
    .mobile-peek-title {
        font-size: 0.95rem;
        font-weight: 600;
        line-height: 1.2;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .mobile-peek-sub {
        font-size: 0.78rem;
        color: var(--text-muted, var(--text-muted));
        line-height: 1.2;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .mobile-peek-chevron {
        flex: 0 0 auto;
        color: var(--text-muted, var(--text-muted));
        transition: transform 0.2s ease;
    }
    .mobile-peek.is-ready {
        background: linear-gradient(180deg, rgba(96, 165, 250, 0.10), var(--bg));
    }
    .mobile-peek.pulse {
        animation: peek-pulse 1.4s ease 1;
    }
    @keyframes peek-pulse {
        0%   { box-shadow: 0 0 0 0 rgba(96, 165, 250, 0.55); }
        70%  { box-shadow: 0 0 0 12px rgba(96, 165, 250, 0); }
        100% { box-shadow: 0 0 0 0 rgba(96, 165, 250, 0); }
    }

    /* When keyboard is open, collapse peek bar to a slim pill so it
       doesn't fight the visible viewport. */
    body.kb-open .mobile-peek {
        min-height: 40px;
        padding: 4px 12px;
    }
    body.kb-open .mobile-peek-thumb {
        width: 32px;
        height: 32px;
    }
    body.kb-open .mobile-peek-sub {
        display: none;
    }
    body.kb-open .mobile-peek-title {
        font-size: 0.85rem;
    }

    /* --- Bottom-sheet preview (the .preview-panel becomes a sheet
       that slides up when peek bar is tapped) --- */
    .preview-panel {
        position: fixed;
        inset-inline-start: 0;
        inset-inline-end: 0;
        bottom: 0;
        top: 0;
        z-index: 9999;
        margin: 0;
        padding: 14px 16px 0;
        padding-top: max(14px, env(safe-area-inset-top));
        padding-bottom: max(16px, env(safe-area-inset-bottom));
        background: var(--surface-1, #111);
        border-top: 1px solid var(--border, #2a2a2a);
        border-radius: 0;
        box-shadow: 0 -16px 48px rgba(0, 0, 0, 0.55);
        transform: translateY(100%);
        transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1);
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }
    /* Lock the page behind the sheet so the dimmed content can't scroll
       and bleed semi-transparent overlap into the sheet's edges. */
    body.preview-open {
        overflow: hidden;
        position: fixed;
        width: 100%;
    }
    body.preview-open .preview-panel {
        transform: translateY(0);
    }
    /* Close (X) button for the full-screen sheet. Floats top-right above
       the QR + actions. Hidden on desktop. */
    .preview-close {
        display: none;
    }
    body.preview-open .preview-close {
        display: flex;
        position: sticky;
        top: 0;
        align-self: flex-end;
        margin-inline-start: auto;
        margin-bottom: var(--space-1);
        width: 40px;
        height: 40px;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: 50%;
        background: rgba(255, 255, 255, 0.06);
        color: var(--text, var(--text));
        cursor: pointer;
        z-index: 10;
    }
    body.preview-open .preview-close:active {
        background: rgba(255, 255, 255, 0.12);
    }
    /* Backdrop */
    .preview-backdrop {
        position: fixed;
        inset: 0;
        z-index: 9990;
        background: rgba(0, 0, 0, 0.55);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
    }
    body.preview-open .preview-backdrop {
        opacity: 1;
        pointer-events: auto;
    }

    /* Inside the sheet, vertical-stack the export buttons full-width. */
    body.preview-open .export-buttons {
        flex-direction: column;
        gap: 10px;
    }
    body.preview-open .export-buttons > * {
        width: 100%;
        min-height: 48px;
    }

    /* --- Sticky bottom Download CTA --- */
    .mobile-cta {
        display: flex;
        gap: var(--space-2);
        position: fixed;
        inset-inline-start: 0;
        inset-inline-end: 0;
        bottom: 0;
        z-index: 45;
        padding: 10px 14px;
        padding-bottom: max(10px, env(safe-area-inset-bottom));
        background: linear-gradient(180deg, rgba(10, 10, 10, 0), var(--bg, #0a0a0a) 30%);
        pointer-events: none;
    }
    .mobile-cta-btn {
        pointer-events: auto;
        flex: 1 1 auto;
        min-height: 52px;
        border-radius: 12px;
        border: 0;
        font: inherit;
        font-size: 1rem;
        font-weight: 600;
        background: var(--blue, var(--blue));
        color: #0a0a0a;
        cursor: pointer;
        box-shadow: 0 6px 20px rgba(96, 165, 250, 0.35);
    }
    /* Idle state: visually muted but still tappable. Tapping scrolls the
       generator form into view so the user can start filling it in. */
    .mobile-cta-btn.idle {
        background: #2a2a2a;
        color: var(--text, var(--text));
        box-shadow: none;
    }
    .mobile-cta-btn:disabled {
        background: #2a2a2a;
        color: var(--text-muted, var(--text-muted));
        cursor: not-allowed;
        box-shadow: none;
    }
    /* In the bottom sheet, the scanability pill normally hangs off the
       bottom of the preview as an absolute pill, on small screens it
       lands right on top of the QR. Pull it out of absolute positioning
       so it flows below the QR as its own line. */
    body.preview-open .scanability-badge {
        position: static;
        bottom: auto;
        inset-inline-end: auto;
        margin: 12px auto 0;
        display: inline-block;
    }
    body.preview-open .qr-preview {
        display: flex;
        flex-direction: column;
        align-items: center;
        margin-bottom: 28px;
        padding: 12px 8px 0;
        min-height: auto;
    }
    body.preview-open .quick-actions {
        margin-top: var(--space-5);
        flex-wrap: wrap;
        gap: 10px;
    }
    /* Mobile recents: lifted .history-panel rendered as a horizontal-
       scrolling row of compact thumb cards above the form. Always
       visible when the user has at least one saved code; collapses to
       nothing (renderHistory() sets display:none) for first-time users.
       Pattern: Spotify "Recently played" / Canva mobile recents. */
    .history-panel.mobile-recents {
        margin: 12px 16px 0;
        border-radius: 12px;
        padding: 10px 10px 8px;
    }
    .history-panel.mobile-recents .history-header {
        margin-bottom: 6px;
        padding: 0 2px;
    }
    .history-panel.mobile-recents .history-list {
        display: flex;
        grid-template-columns: none;
        gap: var(--space-2);
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x mandatory;
        padding-bottom: 2px;
        scrollbar-width: thin;
    }
    .history-panel.mobile-recents .history-item {
        flex: 0 0 auto;
        width: 72px;
        height: 72px;
        scroll-snap-align: start;
    }
    /* Hide the sticky CTA when the preview sheet is open or keyboard up */
    body.preview-open .mobile-cta,
    body.kb-open .mobile-cta {
        display: none;
    }

    /* --- Tap target sweep --- */
    .job-starter {
        min-height: 56px;
    }
    .panel-tab {
        min-height: 44px;
    }
    .btn,
    .btn-sm {
        min-height: 44px;
    }
    /* Hide field hints on phones, they push form down. A tap-to-reveal
       could replace this in a follow-up; for now, keep the form tight. */
    .field-hint {
        display: none;
    }

    /* iOS auto-zoom-on-focus prevention. Safari zooms the viewport when a
       focused input has computed font-size < 16px. Desktop uses 0.9375rem
       (15px) for density; on mobile we bump to 1rem so the page never
       zooms when the keyboard opens. The proper fix instead of breaking
       pinch-zoom for accessibility (which iOS overrides anyway and which
       fails WCAG 2.1 SC 1.4.4 on Android). */
    .field-group input:not([type="checkbox"]):not([type="file"]):not([type="color"]),
    .field-group textarea,
    .field-group select {
        font-size: 1rem;
    }

    /* Make room at the bottom of the page for the sticky CTA. */
    body:not(.preview-open):not(.kb-open) .footer,
    body:not(.preview-open):not(.kb-open) .seo-content:last-of-type {
        padding-bottom: var(--space-20);
    }
}

@media (max-width: 640px) {
    /* Bump tile padding up so labels read comfortably and tap target is
       at the 48px line. Existing rule used 14px 8px / 0.78rem. */
    .job-starter {
        padding: 16px 10px;
        font-size: 0.82rem;
    }
    .job-starters-grid {
        gap: 10px;
    }
    /* Stack export buttons full-width so each is a clear tap target. */
    .export-buttons {
        flex-direction: column;
        gap: 10px;
    }
    .export-buttons > .btn {
        width: 100%;
    }
}

/* =============================================================
   Phase 1.3, utility classes replacing former inline styles.
   - .mt-1 / .mt-2: 4/8px top margin (8/4 grid)
   - .input-uppercase: uppercase text on form inputs (AAMVA, Code39,
     Code93, VIN, short codes that are conventionally uppercase)
   - .d-inline-flex: display:inline-flex one-off
   - .wifi-eap-fields: bordered surface around the EAP advanced block
   ============================================================= */
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.d-inline-flex { display: inline-flex; }
.input-uppercase { text-transform: uppercase; }
.wifi-eap-fields {
    margin-top: var(--space-2);
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
}

/* --- Menu builder (B1) --- */
/* Section + item rows for the inline-encoded menu QR. Styling reuses
   existing tokens; the goal is structural consistency with the rest of
   the form, not a bespoke design surface. */
.menu-sections {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: var(--space-2);
}
.menu-section {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: var(--space-2);
    background: var(--surface-2);
}
.menu-section-head {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    margin-bottom: var(--space-2);
}
.menu-section-head .menu-section-name {
    flex: 1;
    font-weight: 600;
}
.menu-items {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}
.menu-item {
    display: grid;
    grid-template-columns: 1fr 100px auto;
    gap: var(--space-2);
    align-items: start;
}
.menu-item .extra-fields {
    grid-column: 1 / -1;
}
.menu-row-controls {
    display: inline-flex;
    gap: 4px;
}
.menu-row-controls .btn-icon {
    border: 1px solid var(--border);
    background: var(--surface);
    padding: 4px 8px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
}
.menu-row-controls .btn-icon:hover { background: var(--surface-2); }

/* Payload byte counter colour states, applied to #payload-meta when
   the active type is menu / linkinbio (the alphanumeric pipeline). */
#payload-meta.payload-meta-fits { color: #2a7a3e; }
#payload-meta.payload-meta-tight { color: #b87308; }
#payload-meta.payload-meta-overflow { color: #b1271a; font-weight: 600; }

.payload-meta-banner {
    border: 1px solid #b1271a;
    background: #fdecea;
    color: #6a160d;
    padding: var(--space-2);
    border-radius: 6px;
    margin-top: var(--space-2);
}

/* Breadcrumb nav, added 2026-05-09 to satisfy Google's "BreadcrumbList JSON-LD must reflect visible content" policy. */
.breadcrumb { padding: 14px 24px; max-width: 1200px; margin: 0 auto; font-size: 0.875rem; color: var(--muted, #a1a1aa); }
.breadcrumb a { color: var(--muted, #a1a1aa); text-decoration: none; transition: color .15s; }
.breadcrumb a:hover { color: var(--fg, #fafafa); }
.breadcrumb .sep { margin: 0 8px; opacity: 0.5; }
.breadcrumb .current { color: var(--fg, #fafafa); }
@media (max-width: 640px) { .breadcrumb { padding: 12px 16px; font-size: 0.8125rem; } }

/* --- Nav-only earlier breakpoint -------------------------------------
   Force the hamburger drawer at <= 1024px so the in-between range
   (tablets / small laptops) doesn't cram 10 nav items + lang select
   against the logo. Content rules still collapse at the original 768px;
   only nav presentation moves. */
@media (max-width: 1024px) {
    .nav-hamburger { display: inline-flex; }
    .header-nav {
        position: fixed;
        top: var(--space-16);
        inset-inline-end: var(--space-3);
        inset-inline-start: var(--space-3);
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
        padding: 14px;
        background: var(--surface-1);
        border: 1px solid var(--border-hover);
        border-radius: var(--radius-lg);
        box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
        z-index: 1550;
        transform: translateY(-12px);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: transform 0.2s, opacity 0.2s, visibility 0s linear 0.2s;
    }
    body.nav-open .header-nav {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transition: transform 0.2s, opacity 0.2s;
    }
    body.nav-open::after {
        content: "";
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.45);
        z-index: 1540;
        pointer-events: none;
    }
    body.nav-open { overflow: hidden; }
    .header-nav .nav-link,
    .header-nav .nav-btn { padding: 12px 14px; width: 100%; justify-content: flex-start; border-radius: var(--radius); font-size: 0.9375rem; }
    .header-nav .lang-switcher { width: 100%; padding: 12px 32px 12px 14px; font-size: 0.9375rem; }
    /* Closed: hide everything except hamburger + sign-link */
    .header-nav .nav-link:not(.sign-link) { display: none; }
    .nav-btn { padding: 6px 8px; font-size: 0; }
    .nav-btn svg { width: 18px; height: 18px; }
    body.nav-open .header-nav .nav-link,
    body.nav-open .header-nav .nav-drawer-only { display: flex; }
    body.nav-open .header-nav .nav-btn { font-size: 0.9375rem; padding: 12px 14px; }
}

/* Prevent nav items from wrapping or the logo from being squeezed into
   them at any desktop width above the breakpoint above. */
.site-header { gap: 12px; flex-wrap: nowrap; min-width: 0; }
.logo { flex-shrink: 0; }
.header-nav { flex-wrap: nowrap; }
.nav-link, .nav-btn { white-space: nowrap; flex-shrink: 0; }

/* Tappable field values inside .scan-parsed-card, phone numbers, emails,
   and URLs render as the action affordance themselves (no separate button
   stack). Mirrors iOS / Android contact-app convention so users don't have
   to match a "Call" button to the right phone-row by index. */
.scan-parsed-fields dd a.scan-field-link {
    color: var(--blue, var(--blue));
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    font-weight: 500;
    word-break: break-word;
}
.scan-parsed-fields dd a.scan-field-link:hover { text-decoration: underline; }
.scan-parsed-fields dd a.scan-field-link .scan-field-icon {
    font-size: 0.85em;
    opacity: 0.65;
    flex-shrink: 0;
}

/* Header brand mark, sized to match the original inline SVG (28px),
   rounded to match the family squircle. */
.logo .logo-mark {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  flex-shrink: 0;
}

/* Image-frame editor */
#image-frame-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 0;
}
#image-frame-preview {
  max-width: 100%;
  max-height: 400px;
  display: block;
  margin: 0 auto;
  border: 1px solid var(--border, #d0d0d0);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  touch-action: none;
  cursor: grab;
  background: var(--text);
}
#image-frame-preview.dragging {
  cursor: grabbing;
}
#image-frame-row .image-frame-slider-row input[type="range"] {
  flex: 1;
}
#image-frame-row .field-hint {
  font-size: 12px;
  color: var(--text-muted, #666);
  margin: 4px 0 0;
}

/* Frame-mode segmented control */
.frame-mode-row .segmented {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-2);
}
.frame-mode-row .segmented input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px;
  height: 1px;
}
.frame-mode-row .segmented label {
  padding: 6px 12px;
  font-size: 13px;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
  border: 0;
  background: transparent;
  transition: background var(--motion-emphasized, 200ms), color var(--motion-emphasized, 200ms);
}
.frame-mode-row .segmented label + input + label {
  border-left: 1px solid var(--border);
}
.frame-mode-row .segmented input[type="radio"]:checked + label {
  background: var(--surface-3);
  color: var(--text);
}
.frame-mode-row .segmented input[type="radio"]:focus-visible + label {
  outline: 2px solid var(--blue);
  outline-offset: -2px;
}

/* Canonical clipboard-button feedback — matches the abundera-shared
   standard exactly (sign's dashboard.css is the reference): icon-color only,
   no border/layout shift. The two !important are canon-mandated (they must
   beat per-page button color rules). */
.is-copied {
  color: var(--green) !important;
}
.is-copy-failed {
  color: var(--red) !important;
}
