/* ShopWatch - BetterStack-inspired design */

:root {
    /* #957 S-2: the site ships dark-only, so :root IS the dark palette. The light
       values live in html.sw-light below for the day a theme toggle returns;
       every component is written against these tokens, never against a raw
       hex text colour (tests/Smoke/DesignTokenScaleTest guards the count). */
    color-scheme: dark;
    --sw-brand: #3B82F6;
    --sw-brand-dark: #2563EB;
    --sw-brand-light: #93C5FD;
    --sw-brand-tint: rgba(59, 130, 246, 0.14);
    /* Accessible blue: the bright brand (#3B82F6) only hits ~3:1 on white,
       so solid CTAs and brand-colored *text* on light use a deeper blue.
       --sw-brand-text is theme-aware (lighter in dark mode + dark sections). */
    --sw-brand-strong: #1D4ED8;
    --sw-brand-strong-hover: #1E40AF;
    --sw-brand-text: #93C5FD;
    /* Danger / error - decoupled from the brand so the score traffic light and
       error states stay red even though the brand is now green. */
    --sw-danger: #EF4444;
    --sw-danger-dark: #DC2626;
    --sw-danger-tint: rgba(239, 68, 68, 0.16);
    --sw-text: #e8ecf0;
    --sw-text-secondary: #8fa3bb;
    --sw-text-muted: #8495a8;
    --sw-bg: #161A24;
    --sw-bg-subtle: #1E2535;
    --sw-border: rgba(255, 255, 255, 0.10);
    --sw-footer-bg: #10131C;
    --sw-success: #22c55e;
    --sw-success-dark: #16a34a;
    --sw-warning: #f59e0b;
    /* Icon tiles that carry a real logo: favicons and brand icons are drawn for
       light browser tabs, and dark marks vanish on a dark tile. */
    --sw-icon-tile-img-bg: #EEF2F7;
    /* History calendar: a scanned day and a day without data, both quiet fills. */
    --sw-history-cell-base: rgba(255, 255, 255, 0.08);
    --sw-history-cell-noscan: rgba(255, 255, 255, 0.03);
    /* Radius scale (#957 S-1): every rounded corner takes one of these. */
    --sw-radius-xs: 4px;        /* hairline boxes, tags */
    --sw-radius-sm: 6px;        /* small chips, code, thumbnails */
    --sw-radius-control: 8px;   /* inputs, buttons that are not pills, icon boxes */
    --sw-radius-inline: 10px;   /* rows, inline boxes, nudges */
    --sw-radius-card: 14px;     /* the standard card */
    --sw-radius-panel: 16px;    /* large surfaces: panels, bento cells, modals */
    --sw-radius-btn: 9999px;    /* pills */
    --sw-radius-lg: var(--sw-radius-panel);
    /* Card padding scale (#957 S-1) */
    --sw-card-pad-sm: .875rem 1.25rem;
    --sw-card-pad-md: 1.25rem 1.5rem;
    --sw-card-pad-lg: 2rem;
    /* Type scale (#957 S-1, D-19): 11 steps, rem only, every font-size on the site is one of them. */
    --sw-text-2xs: .6875rem;    /* 11px eyebrows */
    --sw-text-xs: .75rem;       /* 12px labels, badges */
    --sw-text-sm: .8125rem;     /* 13px meta, table cells */
    --sw-text-base: .875rem;    /* 14px UI copy */
    --sw-text-md: .9375rem;     /* 15px card copy */
    --sw-text-lg: 1rem;         /* 16px body */
    --sw-text-xl: 1.125rem;     /* 18px card headings, leads */
    --sw-text-2xl: 1.25rem;     /* 20px section headings in cards */
    --sw-text-3xl: 1.5rem;      /* 24px page section headings */
    --sw-text-4xl: 1.75rem;     /* 28px app h1 */
    --sw-text-5xl: 2rem;        /* 32px marketing section headings; heroes keep their own clamp */

    /* Sticky-header heights - single source of truth for anchor scroll offsets
       (analytics jump nav). Change here and navbar + offsets stay in sync. */
    --sw-navbar-height: 68px;

    /* Spacing scale (4px base) - replaces ad-hoc rem values in app surfaces */
    --sw-space-1: 0.25rem;
    --sw-space-2: 0.5rem;
    --sw-space-3: 0.75rem;
    --sw-space-4: 1rem;
    --sw-space-5: 1.5rem;
    --sw-space-6: 2rem;
    --sw-space-8: 3rem;
    --sw-space-10: 4rem;
    --sw-space-12: 5rem;

    /* Premium elevation */
    --sw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --sw-shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
    --sw-shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.45);
    --sw-shadow-modal: 0 24px 64px rgba(0, 0, 0, 0.55), 0 4px 16px rgba(0, 0, 0, 0.35);

    /* Status tints (filled surfaces) */
    --sw-success-tint: rgba(34, 197, 94, 0.14);
    --sw-warning-tint: rgba(245, 158, 11, 0.14);
    --sw-poor-tint: var(--sw-danger-tint);

    /* Status text in AA contrast on the light tints above */
    --sw-success-text: #4ade80;
    --sw-warning-text: #fbbf24;
    --sw-poor-text: #f87171;
    --sw-uptime-nodata: #2A3550;

    /* "Always-dark" section tokens - aligned with the dark-tech look */
    --sw-dark-bg: #161A24;
    --sw-dark-bg-subtle: #1E2535;

    /* Card surface and a card edge that clears 3:1 against the page (#647).
       Light values are the fallback; the dark block below is what ships. */
    --sw-surface: #1C2230;
    --sw-border-strong: rgba(255, 255, 255, 0.34);

    /* Focus, link hover and disabled states in AA (#648) */
    --sw-focus-ring: var(--sw-brand-light);
    --sw-link-hover: #BFDBFE;
    --sw-disabled-bg: #2A3242;
    --sw-disabled-text: #A3B1C2;
    --sw-dark-text: #e5e7eb;
    --sw-dark-text-secondary: #9ca3af;
    --sw-dark-border: rgba(255, 255, 255, 0.10);
}
/* ── Light palette (fallback, not shipped) ── */
html.sw-light {
    --sw-icon-tile-img-bg: var(--sw-bg-subtle);
    --sw-history-cell-base: rgba(15, 23, 42, 0.07);
    --sw-history-cell-noscan: rgba(15, 23, 42, 0.03);
    color-scheme: light;
    --sw-text: #1a1a1a;
    --sw-text-secondary: #6b7280;
    --sw-bg: #ffffff;
    --sw-bg-subtle: #f9fafb;
    --sw-border: #e5e7eb;
    --sw-surface: #ffffff;
    --sw-border-strong: #cbd5e1;
    --sw-focus-ring: var(--sw-brand-strong);
    --sw-link-hover: #1E40AF;
    --sw-disabled-bg: #e5e7eb;
    --sw-disabled-text: #6b7280;
    --sw-footer-bg: #0F1421;
    --sw-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.06);
    --sw-shadow-md: 0 4px 12px rgba(16, 24, 40, 0.06), 0 2px 4px rgba(16, 24, 40, 0.04);
    --sw-shadow-lg: 0 12px 40px rgba(16, 24, 40, 0.12);
    --sw-shadow-modal: 0 24px 64px rgba(16, 24, 40, 0.18), 0 4px 16px rgba(16, 24, 40, 0.08);
    --sw-brand-tint: #EFF6FF;
    --sw-brand-text: #1D4ED8;
    --sw-success-tint: rgba(34, 197, 94, 0.10);
    --sw-warning-tint: rgba(245, 158, 11, 0.12);
    --sw-danger-tint: #FEF1F1;
    --sw-poor-tint: var(--sw-danger-tint);
    --sw-success-text: var(--sw-success-dark);
    --sw-warning-text: #b45309;
    --sw-poor-text: var(--sw-danger-dark);
    --sw-uptime-nodata: #E5E7EB;
    --sw-text-muted: #9ca3af;
}

/* Subtle blue radial glow on the page - echoes the dark-tech coming-soon /
   pricing ambiance. Fixed so it stays put on scroll; very low alpha so text
   stays legible across all app surfaces. */
html.sw-dark body {
    background-color: var(--sw-bg);
    background-image: radial-gradient(900px 520px at 50% -8%, rgba(59, 130, 246, 0.10), transparent 60%);
    background-attachment: fixed;
    background-repeat: no-repeat;
}

html.sw-dark .sw-sidebar-link.active {
    background: var(--sw-brand-tint);
}

html.sw-dark .sw-shop-selector-option.active {
    background: var(--sw-brand-tint);
}

html.sw-dark .sw-card-icon,
html.sw-dark .sw-modal-icon {
    background: var(--sw-brand-tint);
}

/* Ranking delta pills: brighten text on dark backgrounds for contrast. */

/* Falling movers stay amber in dark mode too. */

/* Podium medals/borders: medal colours stay (deliberate gold/silver/bronze),
   but silver and bronze need lifting against the dark card to read clearly. */

html.sw-dark .sw-form-control {
    background-color: var(--sw-bg-subtle);
    color: var(--sw-text);
}

html.sw-dark .sw-code-block {
    background: #1e293b;
}

html.sw-dark .sw-code-gutter {
    background: #1e293b;
    color: var(--sw-text-secondary); /* #648: line numbers at 5.9:1 instead of 3.0:1 */
}

html.sw-dark .sw-code-content {
    background: var(--sw-bg);
}

html.sw-dark .sw-code-line-highlight {
    background: rgba(250, 204, 21, 0.1);
}

html.sw-dark .sw-code-gutter-highlight {
    background: rgba(250, 204, 21, 0.15);
    color: var(--sw-text);
}

/* highlight.js ships only the light GitHub theme (app.js imports github.min.css);
   its navy/dark token colours vanish on the dark background. GitHub-dark values,
   scoped to our code blocks. */
html.sw-dark .sw-code-block .hljs {
    color: #c9d1d9;
}

html.sw-dark .sw-code-block .hljs-tag,
html.sw-dark .sw-code-block .hljs-punctuation {
    color: #8fa3bb;
}

html.sw-dark .sw-code-block .hljs-name {
    color: #7ee787;
}

html.sw-dark .sw-code-block .hljs-attr {
    color: #79c0ff;
}

html.sw-dark .sw-code-block .hljs-string {
    color: #a5d6ff;
}

html.sw-dark .sw-code-block .hljs-comment {
    color: #8b949e;
}

html.sw-dark .sw-tab-active .sw-tab-count {
    background: var(--sw-brand-tint);
}

html.sw-dark .sw-impersonation-banner {
    background: #b45309;
    color: #fff;
}

html.sw-dark .sw-impersonation-banner a {
    color: #fff;
}

html.sw-dark .sw-footer {
    background: var(--sw-dark-bg);
    box-shadow: 0 -4rem 0 0 var(--sw-dark-bg);
}

html.sw-dark .sw-footer h5,
html.sw-dark .sw-footer-heading {
    color: #d1d5db;
}

html.sw-dark .sw-footer-bottom {
    border-top-color: #1f2937;
}

/* ── Base ── */

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    color: var(--sw-text);
    background: var(--sw-bg);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--sw-brand-text);
    text-decoration: none;
}

a:hover {
    color: var(--sw-link-hover); /* #648: lighten on dark instead of darkening into 3.4:1 */
}

a:focus-visible {
    outline: 2px solid var(--sw-brand-light);
    outline-offset: 2px;
}

/* Screen-reader-only utility: visually hidden but exposed to assistive tech. */
.sw-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Skip-to-content link: hidden until focused by keyboard. */
.sw-skip-link {
    position: absolute;
    top: -100%;
    left: 1rem;
    z-index: 9999;
    background: var(--sw-brand-strong);
    color: #fff !important;
    padding: 0.625rem 1.25rem;
    border-radius: var(--sw-radius-btn);
    font-size: var(--sw-text-base);
    font-weight: 500;
    text-decoration: none;
    transition: top 0.1s;
}

.sw-skip-link:focus-visible {
    top: 1rem;
    outline: 3px solid var(--sw-brand-light);
    outline-offset: 2px;
}

/* ── Navbar ── */

.sw-navbar {
    background: var(--sw-footer-bg);
    height: var(--sw-navbar-height);
    display: flex;
    align-items: center;
    border-bottom: none;
    border-top: 3px solid var(--sw-brand);
    /* Sticky so it always covers the top of the viewport. The sticky sidebar and
       analytics tab-nav are offset to sit flush beneath it; without this the
       navbar scrolled away and content showed through above those bars. */
    position: sticky;
    top: 0;
    z-index: 1000;
}

.sw-navbar .container {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    height: 100%;
}

.sw-navbar-brand {
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    color: #fff !important;
    text-decoration: none;
    letter-spacing: -0.03em;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.sw-navbar-brand:hover {
    color: #fff !important;
}

.sw-navbar-logo {
    width: 26px;
    height: 26px;
    color: var(--sw-brand-text);
    flex-shrink: 0;
}

.sw-navbar-brand:hover .sw-navbar-logo {
    animation: sw-logo-beat 1.6s ease-in-out infinite;
}

.sw-navbar-brand:hover .sw-navbar-logo-pulse {
    animation: sw-pulse-heartbeat 1.6s ease-in-out infinite;
}

@keyframes sw-logo-beat {
    0%, 12%   { transform: scale(1); }
    20%       { transform: scale(1.14); }
    28%       { transform: scale(1); }
    34%       { transform: scale(1.07); }
    42%, 100% { transform: scale(1); }
}

@keyframes sw-pulse-heartbeat {
    0%, 12%   { d: path("M9 16 L12.5 16 L14.5 16   L17.5 16   L19.5 16 L23 16"); }
    20%       { d: path("M9 16 L12.5 16 L14.5 10.5 L17.5 21.5 L19.5 16 L23 16"); }
    28%       { d: path("M9 16 L12.5 16 L14.5 16   L17.5 16   L19.5 16 L23 16"); }
    34%       { d: path("M9 16 L12.5 16 L14.5 13   L17.5 19   L19.5 16 L23 16"); }
    42%, 100% { d: path("M9 16 L12.5 16 L14.5 16   L17.5 16   L19.5 16 L23 16"); }
}

.sw-navbar-brand-accent {
    color: var(--sw-brand-text);
}

/* ── Top navigation (#1114) and the one mobile navigation (#1108) ──
   Desktop: Produkt / Lösungen / Ressourcen open a panel each. Every panel is a
   <details>, so it opens with Enter/Space and works without JavaScript;
   nav_menu_controller only adds Esc, click outside and one open at a time.
   Below 1100px the bar collapses into ONE hamburger (a <details> as well):
   accordion sections and, inside the account area, the account pages. */
.sw-topnav {
    display: none;
    align-items: center;
    gap: 0.25rem;
    list-style: none;
    margin: 0 0 0 0.5rem;
    padding: 0;
}

.sw-topnav__item {
    position: relative;
}

.sw-topnav__trigger,
.sw-topnav__link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-height: 44px;
    padding: 0.5rem 0.75rem;
    border-radius: var(--sw-radius-control);
    color: var(--sw-dark-text-secondary);
    font-size: var(--sw-text-base);
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    list-style: none;
    transition: color 0.15s, background 0.15s;
}

.sw-topnav__trigger::-webkit-details-marker,
.sw-navmobile__section > summary::-webkit-details-marker,
.sw-navmobile__toggle::-webkit-details-marker {
    display: none;
}

.sw-topnav__trigger:hover,
.sw-topnav__link:hover,
.sw-topnav__details[open] > .sw-topnav__trigger {
    color: var(--sw-dark-text);
    background: color-mix(in srgb, var(--sw-dark-text) 8%, transparent);
}

.sw-topnav__trigger.is-current,
.sw-topnav__link.is-current {
    color: var(--sw-brand-text);
}

.sw-topnav__trigger:focus-visible,
.sw-topnav__link:focus-visible,
.sw-topnav__panel a:focus-visible,
.sw-navmobile__toggle:focus-visible,
.sw-navmobile__section > summary:focus-visible,
.sw-navmobile__link:focus-visible {
    outline: 2px solid var(--sw-focus-ring);
    outline-offset: 2px;
}

.sw-topnav__chevron {
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

.sw-topnav__details[open] > .sw-topnav__trigger .sw-topnav__chevron,
.sw-navmobile__section[open] > summary .sw-topnav__chevron {
    transform: rotate(180deg);
}

.sw-topnav__panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: -0.5rem;
    z-index: 30;
    display: grid;
    gap: 0.125rem;
    min-width: 340px;
    padding: 0.5rem;
    background: var(--sw-surface);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-panel);
    box-shadow: var(--sw-shadow-lg);
}

.sw-topnav__panel--wide {
    grid-template-columns: 1fr 1fr;
    min-width: 560px;
}

/* One entry: icon, title, one benefit line. Shared by the desktop panels and the mobile accordion. */
.sw-naventry {
    display: grid;
    grid-template-columns: 36px 1fr;
    gap: 0.75rem;
    align-items: start;
    min-height: 44px;
    padding: 0.625rem 0.75rem;
    border-radius: var(--sw-radius-inline);
    color: var(--sw-text);
    text-decoration: none;
}

.sw-naventry:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text);
}

.sw-naventry__icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--sw-radius-control);
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
}

.sw-naventry__icon svg {
    width: 20px;
    height: 20px;
}

.sw-naventry__title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--sw-text-base);
    font-weight: 600;
    line-height: 1.3;
}

.sw-naventry__desc {
    display: block;
    margin-top: 0.125rem;
    font-size: var(--sw-text-sm);
    line-height: 1.4;
    color: var(--sw-text-secondary);
}

.sw-naventry__new {
    font-size: var(--sw-text-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sw-brand-text);
    background: var(--sw-brand-tint);
    border-radius: var(--sw-radius-btn);
    padding: 0.15rem 0.45rem;
}

.sw-topnav__actions {
    display: none;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.sw-topnav__actions .sw-btn {
    white-space: nowrap;
}

/* Hamburger: a <details>, so it opens without JavaScript too. */
.sw-navmobile {
    margin-left: auto;
}

.sw-navmobile__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--sw-dark-border);
    border-radius: var(--sw-radius-control);
    color: var(--sw-dark-text);
    cursor: pointer;
    list-style: none;
}

.sw-navmobile__toggle svg {
    width: 22px;
    height: 22px;
}

.sw-navmobile__toggle .sw-navmobile__close,
.sw-navmobile[open] .sw-navmobile__toggle .sw-navmobile__bars {
    display: none;
}

.sw-navmobile[open] .sw-navmobile__toggle .sw-navmobile__close {
    display: block;
}

.sw-navmobile__panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    max-height: calc(100dvh - var(--sw-navbar-height));
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0.5rem 1rem 1.25rem;
    background: var(--sw-footer-bg);
    border-top: 1px solid var(--sw-dark-border);
    border-bottom: 1px solid var(--sw-dark-border);
    box-shadow: var(--sw-shadow-lg);
}

.sw-navmobile__section {
    border-bottom: 1px solid var(--sw-dark-border);
}

.sw-navmobile__section > summary,
.sw-navmobile__link {
    display: flex;
    align-items: center;
    min-height: 52px;
    color: var(--sw-dark-text);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    list-style: none;
}

.sw-navmobile__section > summary {
    justify-content: space-between;
}

.sw-navmobile__section > summary .sw-topnav__chevron {
    width: 18px;
    height: 18px;
    color: var(--sw-dark-text-secondary);
}

.sw-navmobile__link {
    border-bottom: 1px solid var(--sw-dark-border);
}

.sw-navmobile__link.is-current,
.sw-navmobile__section.is-current > summary {
    color: var(--sw-brand-text);
}

.sw-navmobile__entries {
    display: grid;
    padding-bottom: 0.75rem;
}

.sw-navmobile__entries .sw-naventry {
    padding: 0.5rem 0.25rem;
}

/* The account pages inside the hamburger (the sidebar's links, one list). */
.sw-navmobile__account {
    padding: 0.25rem 0 0.5rem;
    border-bottom: 1px solid var(--sw-dark-border);
}

.sw-navmobile__group-label {
    display: block;
    padding: 0.75rem 0 0.25rem;
    color: var(--sw-dark-text-secondary);
}

.sw-navmobile__account .sw-navmobile__link {
    min-height: 48px;
    gap: 0.75rem;
    border-bottom: 0;
    font-weight: 500;
    font-size: var(--sw-text-md);
}

.sw-navmobile__account .sw-navmobile__link svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

.sw-navmobile__link.is-disabled {
    color: var(--sw-disabled-text);
    cursor: default;
}

.sw-navmobile__actions {
    display: grid;
    gap: 0.625rem;
    margin-top: 1.25rem;
}

.sw-navmobile__actions .sw-btn {
    width: 100%;
    min-height: 48px;
    margin-top: 0;
}

@media (min-width: 1100px) {
    .sw-topnav,
    .sw-topnav__actions {
        display: flex;
    }

    .sw-navmobile {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .sw-topnav__chevron,
    .sw-topnav__trigger,
    .sw-topnav__link {
        transition: none;
    }
}

.sw-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--sw-text-base);
    font-weight: 500;
    border: none;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
    min-height: 44px;
}

.sw-btn:active {
    transform: scale(0.98);
}

.sw-btn-primary {
    background: var(--sw-brand-strong);
    color: #fff !important;
    border-radius: var(--sw-radius-btn);
    padding: 0.5rem 1.25rem;
}

.sw-btn-primary:hover {
    background: var(--sw-brand-strong-hover);
    color: #fff !important;
}

.sw-btn-primary-lg {
    padding: 0.875rem 2rem;
    font-size: var(--sw-text-lg);
    font-weight: 600;
}

.sw-btn-primary.sw-btn-filling {
    background: linear-gradient(to right, var(--sw-brand-strong-hover) 50%, var(--sw-brand-strong) 50%);
    background-size: 200% 100%;
    background-position: 100% 0;
    animation: sw-btn-fill 1000ms linear forwards;
}

@keyframes sw-btn-fill {
    from { background-position: 100% 0; }
    to { background-position: 0% 0; }
}

.sw-btn-outline {
    background: transparent;
    color: var(--sw-text-secondary) !important;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    padding: 0.5rem 1.25rem;
}

.sw-btn-outline:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text) !important;
    border-color: #d1d5db;
}

/* ── CTA button (sw-btn-cta) ──
   Primary action with a nested icon capsule - the arrow never sits naked
   next to text. Composes with the base .sw-btn class like every other
   variant (min-height: auto overrides the base's 44px floor - this button's
   own padding + the 30px icon disc already exceed it, so the override only
   matters for the shorter cases). Reserved for the single highest-priority
   action on a page (e.g. the dashboard stage's "biggest lever"). */
.sw-btn-cta {
    display: inline-flex; align-items: center; gap: 0.6rem; min-height: auto;
    padding: 0.5rem 0.5rem 0.5rem 1.15rem; border: 0; border-radius: var(--sw-radius-btn);
    background: var(--sw-brand-strong); color: #fff; text-decoration: none;
    font-size: var(--sw-text-md); font-weight: 620; cursor: pointer;
    transition: background 0.35s cubic-bezier(0.32,0.72,0,1),
                transform 0.35s cubic-bezier(0.32,0.72,0,1);
}
.sw-btn-cta:hover { background: var(--sw-brand-strong-hover); color: #fff; }
.sw-btn-cta:active { transform: scale(0.985); }
.sw-btn-cta__ico {
    width: 30px; height: 30px; border-radius: var(--sw-radius-btn); display: grid; place-items: center;
    background: rgba(255,255,255,0.16);
    transition: transform 0.35s cubic-bezier(0.32,0.72,0,1);
}
.sw-btn-cta:hover .sw-btn-cta__ico { transform: translate3d(2px,-1px,0) scale(1.05); }
.sw-btn-cta__ico svg { width: 15px; height: 15px; }

/* ── Ghost button (sw-btn-ghost) ──
   Borderline-transparent secondary action, compact enough to sit inline
   with body copy (e.g. next to a gain badge in the dashboard rail).
   Composes with the base .sw-btn class like sw-btn-cta above - min-height:
   auto overrides the base's 44px floor to keep this button genuinely
   compact. */
.sw-btn-ghost {
    display: inline-flex; align-items: center; gap: 0.4rem; min-height: auto;
    /* Explicitly transparent: neither .sw-btn nor this class used to declare a
       background, which is invisible on an <a> but leaves a <button> with the
       browser's default grey buttonface. Every ghost button rendered as a filled
       light pill; on the dark competitor table it looked like a different
       component entirely. */
    background: transparent;
    padding: 0.5rem 1.05rem; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-btn);
    color: var(--sw-text-secondary); text-decoration: none;
    font-size: var(--sw-text-base); font-weight: 560;
    transition: background 0.35s cubic-bezier(0.32,0.72,0,1), color 0.35s cubic-bezier(0.32,0.72,0,1);
}
.sw-btn-ghost:hover { background: rgba(255,255,255,0.05); color: var(--sw-text); }

/* Navbar dark button overrides */
.sw-navbar .sw-btn-outline {
    color: #9ca3af !important;
    border-color: #374151;
}

.sw-navbar .sw-btn-outline:hover {
    background: #1f2937;
    color: #fff !important;
    border-color: #4b5563;
}


/* ── Hero ── */

.sw-hero {
    text-align: center;
    padding: 6rem 0 4rem;
}

.sw-hero h1 {
    font-size: 3.5rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--sw-text);
    margin-bottom: 1.5rem;
}

.sw-hero-gradient {
    background: linear-gradient(90deg, var(--sw-brand-light), var(--sw-brand), var(--sw-brand-strong), var(--sw-brand), var(--sw-brand-light));
    background-size: 300% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: sw-gradient-shift 6s ease infinite;
}

@keyframes sw-gradient-shift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

.sw-hero .sw-hero-sub {
    font-size: var(--sw-text-2xl);
    color: var(--sw-text-secondary);
    max-width: 600px;
    margin: 0 auto 2.5rem;
    line-height: 1.6;
}

@keyframes sw-cursor-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
}

/* ── Section ── */

.sw-section {
    padding: 5rem 0;
}

.sw-section-heading {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    text-align: center;
    margin-bottom: 1rem;
}

.sw-section-sub {
    font-size: var(--sw-text-xl);
    color: var(--sw-text-secondary);
    text-align: center;
    max-width: 560px;
    margin: 0 auto 3rem;
}

/* ── Cards ── */

.sw-card {
    background: var(--sw-surface);
    border: 1px solid var(--sw-border-strong);
    border-radius: var(--sw-radius-card);
    padding: var(--sw-card-pad-lg);
    transition: box-shadow 0.2s, transform 0.2s;
    height: 100%;
}

.sw-card:hover {
    box-shadow: none;
    transform: none;
}

.sw-card-icon {
    width: 48px;
    height: 48px;
    border-radius: var(--sw-radius-card);
    background: var(--sw-brand-tint);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.25rem;
}

.sw-card-icon svg {
    width: 24px;
    height: 24px;
    color: var(--sw-brand-text);
}

.sw-card h3 {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    margin-bottom: 0.5rem;
    color: var(--sw-text);
}

.sw-card p {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin-bottom: 0;
    line-height: 1.6;
}

/* ── Auth pages ── */

.sw-auth-wrapper {
    max-width: 400px;
    margin: 4rem auto;
}

.sw-auth-wrapper h1 {
    font-size: var(--sw-text-4xl);
    font-weight: 700;
    text-align: center;
    margin-bottom: 2rem;
    letter-spacing: -0.02em;
}

.sw-form-control {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    padding: 0.625rem 0.875rem;
    font-size: var(--sw-text-md);
    transition: border-color 0.15s, box-shadow 0.15s;
    width: 100%;
    color: var(--sw-text);
}

.sw-form-control:focus {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
    outline: none;
}

.sw-form-label {
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text);
    margin-bottom: 0.375rem;
}

.sw-auth-footer {
    text-align: center;
    margin-top: 1.5rem;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

/* ── Dashboard ── */

.sw-dashboard {
    padding-bottom: 2.5rem;
}

.sw-dashboard h1 {
    font-size: var(--sw-text-4xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 0.5rem;
}

.sw-dashboard .sw-dash-sub {
    color: var(--sw-text-secondary);
    margin-bottom: 2rem;
}

/* Dashboard header: title + primary action on one row */

.sw-placeholder-card {
    background: var(--sw-bg-subtle);
    border: 1px dashed var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 3rem 2rem;
    text-align: center;
    color: var(--sw-text-muted);
}

/* ── Sidebar / App Layout ── */

.sw-app-layout {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    gap: 2rem;
    padding-top: 2.5rem;
}

.sw-sidebar {
    position: sticky;
    top: 92px;
    align-self: start;
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 92px - 2.5rem);
}

/* ── Sidebar Footer ── */

.sw-sidebar-footer {
    margin-top: auto;
    padding-top: 1.5rem;
    border-top: 1px solid var(--sw-border);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.sw-sidebar-feedback-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.625rem 0.75rem;
    background: var(--sw-brand-tint);
    border: 1px solid transparent;
    border-radius: var(--sw-radius-control);
    cursor: pointer;
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-brand-text);
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.1s;
}

.sw-sidebar-feedback-btn:hover {
    background: var(--sw-brand-strong);
    border-color: var(--sw-brand-strong);
    color: #fff;
    box-shadow: 0 4px 14px rgba(29, 78, 216, 0.28);
}

.sw-sidebar-feedback-btn:active {
    transform: scale(0.98);
}

.sw-sidebar-feedback-btn:focus-visible {
    outline: none;
    border-color: var(--sw-brand-strong);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

.sw-sidebar-feedback-btn svg {
    flex-shrink: 0;
}

/* Feedback modal inline status - scoped classes so they never collide with the
   global .sw-alert-* flash-message selectors used in account-page assertions. */
/* #904: the feedback modal used its own hard-coded pair of colours. Same tones,
   same tokens, same radius as the alert family now - one less era in the CSS. */
.sw-feedback-alert {
    padding: 0.9rem 1.15rem;
    border: 1px solid color-mix(in srgb, var(--alert-accent, var(--sw-brand)) 30%, transparent);
    border-radius: var(--sw-radius-card);
    font-size: var(--sw-text-md);
    line-height: 1.5;
    margin-bottom: 1rem;
}

.sw-feedback-alert--error {
    --alert-accent: var(--sw-danger);
    background: var(--sw-danger-tint);
    color: var(--sw-poor-text);
}

.sw-feedback-alert--success {
    --alert-accent: var(--sw-success);
    background: var(--sw-success-tint);
    color: var(--sw-success-text);
    padding: 1.25rem 1.15rem;
    text-align: center;
}

.sw-sidebar-profile {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}

.sw-sidebar-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    flex-shrink: 0;
}

.sw-sidebar-profile-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.sw-sidebar-profile-name {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sw-sidebar-profile-email {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sw-sidebar-logout {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border-radius: var(--sw-radius-control);
    color: var(--sw-text-muted);
    transition: color 0.15s, background 0.15s;
}

.sw-sidebar-logout:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-brand-text);
}

/* ── Shop Selector ── */

.sw-shop-selector {
    position: relative;
    margin-top: var(--sw-space-4);
    margin-bottom: 1rem;
}

.sw-shop-selector-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    cursor: pointer;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text);
    text-align: left;
    transition: border-color 0.15s;
}

.sw-shop-selector-toggle:hover {
    border-color: #d1d5db;
}

.sw-shop-selector-toggle:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
    border-radius: var(--sw-radius-control);
}

.sw-shop-selector-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    color: var(--sw-text-muted);
}

.sw-shop-selector-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Warning dot: shop can't be analyzed (unreachable). Amber, so it reads as
   "attention" without the alarm of a red error state. */
.sw-shop-warn-dot {
    flex-shrink: 0;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--sw-warning);
    box-shadow: 0 0 0 3px var(--sw-warning-tint);
}
/* The option is display:block, so the dot needs inline-block to take a size. */
.sw-shop-selector-option .sw-shop-warn-dot {
    display: inline-block;
    vertical-align: middle;
    margin-left: 6px;
}

.sw-shop-selector-chevron {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    color: var(--sw-text-muted);
    transition: transform 0.15s;
}

.sw-shop-selector-menu {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    box-shadow: var(--sw-shadow-md);
    z-index: 50;
    max-height: 240px;
    overflow-y: auto;
    padding: 4px;
}

.sw-shop-selector-menu.sw-shop-selector-open {
    display: block;
}

.sw-shop-selector-open .sw-shop-selector-chevron {
    transform: rotate(180deg);
}

.sw-shop-selector-option {
    display: block;
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    border-radius: var(--sw-radius-sm);
    cursor: pointer;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-secondary);
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s;
}

.sw-shop-selector-option:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text);
}

.sw-shop-selector-option:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
    border-radius: var(--sw-radius-sm);
}

.sw-shop-selector-option.active {
    color: var(--sw-brand-text);
    background: var(--sw-brand-tint);
}

.sw-sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sw-sidebar-group-label {
    padding: 0 0.75rem;
    margin-bottom: var(--sw-space-1);
}

.sw-sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary) !important;
    text-decoration: none;
    padding: 0.5rem 0.75rem;
    border-radius: var(--sw-radius-control);
    transition: color 0.15s, background 0.15s;
    min-height: 44px;
}

.sw-sidebar-link svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

.sw-sidebar-link:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text) !important;
}

.sw-sidebar-link.active {
    color: var(--sw-brand-text) !important;
    background: var(--sw-brand-tint);
}

.sw-sidebar-link-disabled {
    opacity: 0.4;
    pointer-events: none;
    cursor: default;
}

/* Shown below the Insights group label when the user has no shops yet. */
.sw-sidebar-insights-hint {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
    margin: 0.125rem 0 0.375rem 0.75rem;
    line-height: 1.3;
}

/* ── Footer ── */

.sw-footer {
    background: var(--sw-footer-bg);
    color: var(--sw-text-muted);
    padding: 4rem 0 2rem;
    margin-top: 4rem;
}

.sw-footer h5,
.sw-footer-heading {
    color: #fff;
    font-size: var(--sw-text-base);
    font-weight: 600;
    margin-bottom: 1rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.sw-footer a {
    color: var(--sw-text-muted);
    font-size: var(--sw-text-base);
    display: inline-block;
    padding-block: 0.35rem; /* #953 P-13: a tap target, not a hairline */
    text-decoration: none;
    transition: color 0.15s;
}

.sw-footer a:hover {
    color: #fff;
}

.sw-footer-bottom {
    border-top: 1px solid #1f2937;
    margin-top: 3rem;
    padding-top: 1.5rem;
    font-size: var(--sw-text-sm);
    color: #6b7280;
}

/* ── Alerts ── */

/* Flash and inline alerts (#904). Same build as .sw-notice further down - a
   tone-coloured icon tile, then the message - so a flash and a status notice on
   the same page read as one family instead of two eras of the design system.

   The icon is drawn from two pseudo-elements: ::before is the tile, ::after is
   the glyph laid over it. That way every one of the 33 places that writes a bare
   <div class="sw-alert-warning">…</div> gets the full treatment without markup.

   All three colours come from theme-aware tokens, so dark mode needs no override
   of its own - the four html.sw-dark rules this replaced are gone. No coloured
   left edge anywhere: tinted surface plus icon carries the tone (founder rule). */
.sw-alert-success,
.sw-alert-error,
.sw-alert-info,
.sw-alert-warning {
    --alert-fg: var(--sw-brand-text);
    --alert-bg: var(--sw-brand-tint);
    --alert-accent: var(--sw-brand);
    position: relative;
    /* #911: a block, not a flex row. As a flex container every child element
       and every run of text became its own column - the bot-wall warning on
       /try stood as three columns side by side, "text <a>link</a> text" fell
       apart at the link. The tile now lives in the left padding instead, and
       whatever the message contains flows the way text flows. A class that
       deliberately lays the alert out as a row (history upsell, limit alerts)
       still sets its own display and keeps working: the tile is positioned,
       not a flex item. */
    display: block;
    padding: 0.9rem 1.15rem 0.9rem calc(1.15rem + 34px + 0.875rem);
    background: var(--alert-bg);
    border: 1px solid color-mix(in srgb, var(--alert-accent) 30%, transparent);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    color: var(--alert-fg);
    font-size: var(--sw-text-md);
    font-weight: 500;
    line-height: 1.5;
    margin-bottom: 1.25rem;
}

/* The tile, centred on the FIRST line of the message (1lh = one line of
   the alert's text). A one-line flash looks exactly as before; a paragraph
   keeps its tile next to its opening line instead of halfway down (#911). */
.sw-alert-success::before,
.sw-alert-error::before,
.sw-alert-info::before,
.sw-alert-warning::before {
    content: "";
    position: absolute;
    left: 1.15rem;
    top: calc(0.9rem + (1lh - 34px) / 2);
    width: 34px;
    height: 34px;
    border-radius: var(--sw-radius-inline);
    background: color-mix(in srgb, var(--alert-accent) 16%, transparent);
}

/* The glyph, centred on the tile. */
.sw-alert-success::after,
.sw-alert-error::after,
.sw-alert-info::after,
.sw-alert-warning::after {
    content: "";
    position: absolute;
    left: calc(1.15rem + 17px);
    top: calc(0.9rem + 0.5lh);
    width: 19px;
    height: 19px;
    transform: translate(-50%, -50%);
    background-color: currentColor;
    -webkit-mask: var(--sw-alert-icon) center / contain no-repeat;
    mask: var(--sw-alert-icon) center / contain no-repeat;
}

.sw-alert-error {
    --sw-alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23000' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z'/%3E%3C/svg%3E");
    --alert-fg: var(--sw-poor-text);
    --alert-bg: var(--sw-danger-tint);
    --alert-accent: var(--sw-danger);
}

.sw-alert-success {
    --sw-alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23000' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z'/%3E%3C/svg%3E");
    --alert-fg: var(--sw-success-text);
    --alert-bg: var(--sw-success-tint);
    --alert-accent: var(--sw-success);
}

.sw-alert-info {
    --sw-alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23000' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z'/%3E%3C/svg%3E");
    --alert-fg: var(--sw-brand-text);
    --alert-bg: var(--sw-brand-tint);
    --alert-accent: var(--sw-brand);
}

.sw-alert-warning {
    --sw-alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23000' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z'/%3E%3C/svg%3E");
    --alert-fg: var(--sw-warning-text);
    --alert-bg: var(--sw-warning-tint);
    --alert-accent: var(--sw-warning);
}

/* Blocks inside an alert (a title, paragraphs, a list) keep their rhythm but
   do not add space at the edges of the box. */
.sw-alert-success > :first-child,
.sw-alert-error > :first-child,
.sw-alert-info > :first-child,
.sw-alert-warning > :first-child {
    margin-top: 0;
}
.sw-alert-success > :last-child,
.sw-alert-error > :last-child,
.sw-alert-info > :last-child,
.sw-alert-warning > :last-child {
    margin-bottom: 0;
}

/* The guarantee-notice heads-up on the dashboard: a plain info banner (not an upsell). */
.sw-heads-up {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    flex-wrap: wrap;
}
.sw-heads-up__text { flex: 1 1 28rem; }
.sw-heads-up__text strong { display: block; margin-bottom: 0.125rem; color: var(--sw-text); }
.sw-heads-up__cta { flex-shrink: 0; }
.sw-dash3 .sw-heads-up { margin-top: 2.25rem; }

/* #504: on the dashboard the plan nudge follows the coaching rail, which has no
   bottom margin, so the note hugged the previous block. Match the 2.25rem
   section rhythm (.sw-brief / .sw-rail). */
.sw-dash3 .sw-plan-nudge { margin-top: 2.25rem; }

.sw-form-check {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.sw-form-check input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    accent-color: var(--sw-brand-text);
}

.sw-form-check .sw-form-check-label,
.sw-form-check label {
    margin: 0;
    font-size: var(--sw-text-base);
    font-weight: 500;
}

.sw-form-help {
    flex-basis: 100%;
}

/* ── Button disabled ── */

.sw-btn-disabled {
    /* #648: real disabled colours instead of fading the control (text 5.9:1 on dark) */
    background: var(--sw-disabled-bg);
    border-color: var(--sw-disabled-bg);
    color: var(--sw-disabled-text);
    box-shadow: none;
    cursor: not-allowed;
    pointer-events: none;
}

/* ── URL status indicator ── */

.sw-url-input-wrapper {
    position: relative;
}

.sw-url-status {
    display: flex;
    align-items: flex-start;
    gap: 0.375rem;
    margin-top: 0.5rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    line-height: 1.45;
    /* Allow a long message (e.g. a DNS failure) to wrap below the bar instead of
       being clamped to one line and overlapping the input. */
    overflow-wrap: anywhere;
}

.sw-url-status:empty { margin-top: 0; }

.sw-url-status svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-top: 1px;
}

.sw-url-status-loading {
    color: var(--sw-text-muted);
}

.sw-url-status-success {
    color: var(--sw-success-dark);
}

.sw-url-status-error {
    color: var(--sw-poor-text); /* #953 D-35: theme-aware, 4.5:1 on dark */
}

.sw-url-status-warning {
    color: var(--sw-warning-text); /* #953 D-35: theme-aware, distinct from brand and danger */
}

/* ── Shops page ── */

.sw-shops {
    padding-bottom: 2.5rem;
}

.sw-shops .sw-dash-sub {
    color: var(--sw-text-secondary);
    margin-bottom: 0;
}

.sw-shop-add-hint {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin-bottom: 1.25rem;
}

.sw-shop-metered-note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    padding: 0.625rem 0.875rem;
    margin-bottom: 1.25rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-shop-metered-note svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--sw-text-muted);
}

.sw-shop-form-row {
    display: flex;
    align-items: flex-end;
    gap: 0.75rem;
}

.sw-shop-form-field {
    flex: 1;
    min-width: 0;
}

.sw-shop-form-row .sw-btn {
    flex-shrink: 0;
}

/* Workspace group heading for the multi-workspace shop list. Deliberately
   understated - heading token, no brand colour and no left-border accent. */

.sw-shop-item {
    padding: var(--sw-card-pad-md);
}

.sw-shop-item:hover {
    transform: none;
}

.sw-shop-item-content {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.sw-shop-item-info {
    flex: 1;
    min-width: 0;
}

.sw-shop-item-content .sw-card-icon {
    margin-bottom: 0;
    flex-shrink: 0;
}

.sw-shop-url {
    font-size: var(--sw-text-md);
    font-weight: 500;
    color: var(--sw-text);
    margin-bottom: 0.125rem;
    word-break: break-all;
}

/* The domain is the row's identifier, not a call-to-action: render it in the
   heading colour (not brand red) while keeping it a working link to the detail
   page. Brand red on the row is reserved for the destructive Remove action. */
.sw-shop-url--neutral {
    color: var(--sw-text);
    font-weight: 600;
}

.sw-shop-url--neutral:hover {
    color: var(--sw-text-secondary);
    text-decoration: underline;
}

.sw-shop-date {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    margin-bottom: 0;
}

.sw-shop-item-actions {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-left: auto;
    flex-shrink: 0;
}

.sw-shop-move-form {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

/* ── Metric widgets ── */

.sw-metric-value {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    color: var(--sw-text);
    letter-spacing: -0.02em;
    line-height: 1.2;
    display: inline-flex;
    align-items: baseline;
    gap: 0.125rem;
}



@keyframes sw-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ── Polling failure notice ── */

.sw-poll-retry {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.sw-poll-retry:hover {
    opacity: 0.8;
}

/* ── Tables ── */

.sw-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--sw-text-base);
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    overflow: hidden;
}

.sw-table th,
.sw-table td {
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--sw-border);
}

.sw-table th {
    font-weight: 600;
    color: var(--sw-text-secondary);
    background: var(--sw-bg-subtle);
    font-size: var(--sw-text-sm);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.sw-table tbody tr:last-child td {
    border-bottom: none;
}

.sw-table tbody tr:hover {
    background: var(--sw-bg-subtle);
}

/* Note: this is a <td> in 6 admin tables (users, shops, waitlist, workspaces,
   jobs, invoices/members) - `display: flex` directly on a table cell gets
   blockified per the CSS Display spec, which takes it out of table-row
   height stretching. That was invisible while every row was short/uniform,
   but became a visible "broken" row divider once a taller multi-line row
   (scheduled-tasks) sat next to a short Actions cell. `vertical-align: middle`
   keeps it a normal table-cell that stretches with its row; margin between
   action buttons replaces the flex `gap`. */
.sw-table-actions {
    vertical-align: middle;
}

.sw-table-actions > * + * {
    margin-left: 0.5rem;
}

.sw-table-meta {
    display: block;
    color: var(--sw-text-muted);
    font-size: var(--sw-text-sm);
    margin-top: 0.125rem;
}

.sw-table-user {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}

.sw-table-avatar {
    border-radius: 50%;
    flex-shrink: 0;
    border: 1px solid var(--sw-border);
    background: var(--sw-bg-subtle);
}

.sw-table-user-name {
    font-weight: 500;
    color: var(--sw-text);
}

.sw-table-count {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-variant-numeric: tabular-nums;
    color: var(--sw-text-secondary);
}

.sw-table-count svg {
    width: 16px;
    height: 16px;
    color: var(--sw-text-muted);
}

.sw-table-actions-col {
    text-align: right;
}

/* ── Admin Layout / Topbar Nav ──
   Admin (`/admin/*`) uses a horizontal nav bar instead of the account sidebar
   so tables get the full container width. Deliberately its OWN class family
   (`sw-admin-*`) - the `.sw-sidebar*` classes are shared with
   `account/_layout.html.twig` and must not be touched here. */

.sw-admin-layout {
    padding-top: 1.5rem;
}

.sw-admin-topbar {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    background: var(--sw-bg);
    margin-bottom: 1.5rem;
    overflow-x: auto;
}

.sw-admin-nav {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0.5rem;
    white-space: nowrap;
}

.sw-admin-nav-link {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary) !important;
    text-decoration: none;
    padding: 0.5rem 0.75rem;
    border-radius: var(--sw-radius-control);
    transition: color 0.15s, background 0.15s;
    flex-shrink: 0;
}

.sw-admin-nav-link svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.sw-admin-nav-link:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text) !important;
}

.sw-admin-nav-link.active {
    color: var(--sw-brand-text) !important;
    background: var(--sw-brand-tint);
}

.sw-admin-nav-divider {
    width: 1px;
    height: 24px;
    background: var(--sw-border);
    margin: 0 0.375rem;
    flex-shrink: 0;
}

/* ── Admin stat tiles ── */

.sw-admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.sw-stat-tile-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--sw-radius-inline);
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
    flex-shrink: 0;
}

.sw-stat-tile-icon svg {
    width: 20px;
    height: 20px;
}

html.sw-dark .sw-stat-tile-icon {
    background: var(--sw-brand-tint);
}

/* ── Card title ── */

.sw-card-title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    margin-bottom: 1.25rem;
}

/* ── Chart container & legend ── */

.sw-chart-box {
    height: 260px;
}

.sw-chart-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 1rem;
    margin: 1rem 0 0;
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
}

.sw-chart-legend .sw-light {
    margin-left: 0.5rem;
}

.sw-chart-legend .sw-light:first-child {
    margin-left: 0;
}

/* ── Queue breakdown ── */

.sw-queue-breakdown {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.sw-queue-chip {
    font-variant-numeric: tabular-nums;
}

.sw-queue-chip strong {
    margin-left: 0.125rem;
    font-weight: 700;
}

.sw-queue-chip--zero {
    opacity: 0.5;
}

.sw-queue-more {
    text-align: center;
    color: var(--sw-text-muted);
    font-size: var(--sw-text-sm);
}

/* ── Workspace summary header ── */

.sw-workspace-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
    padding: 1.125rem 1.5rem;
}

.sw-workspace-summary:hover {
    transform: none;
    box-shadow: none;
}

.sw-workspace-summary-main {
    display: flex;
    align-items: center;
    gap: 0.875rem;
}

.sw-workspace-summary-meta {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    flex-shrink: 0;
}

.sw-workspace-summary-meta .sw-table-meta {
    margin-top: 0;
}

/* ── Small buttons ── */

.sw-btn-sm {
    padding: 0.25rem 0.75rem;
    font-size: var(--sw-text-sm);
    min-height: 36px; /* Compact exception - table/inline contexts */
}

/* ── Danger button ── */

.sw-btn-danger {
    background: transparent;
    color: var(--sw-danger) !important;
    border: 1px solid var(--sw-danger);
    border-radius: var(--sw-radius-btn);
    padding: 0.5rem 1.25rem;
}

.sw-btn-danger:hover {
    background: var(--sw-danger);
    color: #fff !important;
}

/* ── Badge ── */

/* ── Rating chip (#957 S-3): the one pill that says how a value stands. Always
   together with sw_light() and a word - never colour alone (ADR-0008, WCAG 1.4.1).
   Replaces .sw-cmd-chip, .sw-cmd-stat and .sw-md-hero__chip. ── */
.sw-rating-chip { display: inline-flex; align-items: center; gap: .375rem; font-size: var(--sw-text-xs); font-weight: 600; border-radius: var(--sw-radius-btn); padding: .2rem .625rem; border: 1px solid transparent; white-space: nowrap; }
.sw-rating-chip--lg { font-size: var(--sw-text-sm); font-weight: 650; padding: .25rem .75rem; gap: .4rem; }
.sw-rating-chip--good { background: var(--sw-success-tint); color: var(--sw-success-text); border-color: rgba(34, 197, 94, .25); }
.sw-rating-chip--moderate { background: var(--sw-warning-tint); color: var(--sw-warning-text); border-color: rgba(245, 158, 11, .25); }
.sw-rating-chip--poor { background: var(--sw-danger-tint); color: var(--sw-poor-text); border-color: rgba(239, 68, 68, .25); }
.sw-rating-chip--perfect { background: var(--sw-brand-tint); color: var(--sw-brand-text); border-color: var(--sw-brand-light); font-weight: 700; }
.sw-rating-chip--neutral, .sw-rating-chip--empty { background: transparent; color: var(--sw-text-muted); border-color: var(--sw-border); }
.sw-rating-chip__icon { width: 15px; height: 15px; color: var(--sw-brand-light); }

/* ── Eyebrow (#957 S-3): the one small uppercase line over a value or a section.
   Replaces 22 bespoke label rules; --lg for 12px, --brand / --secondary / --light for tone. ── */
.sw-eyebrow { font-size: var(--sw-text-2xs); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--sw-text-muted); }
.sw-eyebrow--lg { font-size: var(--sw-text-xs); }
.sw-eyebrow--brand { color: var(--sw-brand-text); }
.sw-eyebrow--secondary { color: var(--sw-text-secondary); }
.sw-eyebrow--light { color: var(--sw-brand-light); font-weight: 700; }

.sw-badge {
    display: inline-block;
    font-size: var(--sw-text-2xs);
    font-weight: 600;
    padding: 0.125rem 0.5rem;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-bg-subtle);
    color: var(--sw-text-secondary);
    border: 1px solid var(--sw-border);
    letter-spacing: 0.02em;
}

.sw-badge-success {
    background: var(--sw-success-tint);
    color: var(--sw-success-text);
    border-color: rgba(34, 197, 94, 0.25);
}

.sw-badge-muted {
    background: var(--sw-bg-subtle);
    color: var(--sw-text-muted);
    border-color: var(--sw-border);
}

.sw-badge-error {
    background: var(--sw-danger-tint);
    color: var(--sw-poor-text);
    border-color: rgba(239, 68, 68, 0.28);
}

.sw-badge-warning {
    background: var(--sw-warning-tint);
    color: var(--sw-warning-text);
    border-color: rgba(245, 158, 11, 0.25);
}

.sw-badge-info {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
    border-color: rgba(59, 130, 246, 0.3);
}

.sw-badge-brand {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
    border-color: rgba(59, 130, 246, 0.3);
}
/* Sizes and shapes of the one chip (#957 S-3) */
.sw-badge--md { font-size: var(--sw-text-xs); padding: 0.25rem 0.75rem; }
.sw-badge--upper { text-transform: uppercase; letter-spacing: 0.04em; }
.sw-badge--flex { display: inline-flex; align-items: center; gap: 0.375rem; }

.sw-badge-plan {
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.sw-badge-plan--free {
    background: var(--sw-bg-subtle);
    color: var(--sw-text-secondary);
    border-color: var(--sw-border);
}

.sw-badge-plan--pro {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-dark);
    border-color: #BFDBFE;
}

.sw-badge-plan--agency {
    background: #f5f3ff;
    color: #7c3aed;
    border-color: #ddd6fe;
}

html.sw-dark .sw-badge-plan--pro {
    background: var(--sw-brand-tint);
    border-color: rgba(59, 130, 246, 0.3);
    color: var(--sw-brand-light);
}

html.sw-dark .sw-badge-plan--agency {
    background: rgba(124, 58, 237, 0.12);
    border-color: rgba(124, 58, 237, 0.3);
    color: #a78bfa;
}

/* ── Tabs ── */

.sw-tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var(--sw-border);
    margin-bottom: 1rem;
    /* Six category tabs with counts do not fit a phone: scroll the row, not the page
       (same pattern as .sw-admin-topbar). */
    overflow-x: auto;
}

.sw-tab {
    flex-shrink: 0;
    white-space: nowrap;
    padding: 0.5rem 1rem;
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary);
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}

.sw-tab:hover {
    color: var(--sw-text);
}

.sw-tab-active {
    color: var(--sw-brand-text);
    border-bottom-color: var(--sw-brand-text);
}

.sw-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.375rem;
    margin-left: 0.375rem;
    font-size: var(--sw-text-2xs);
    font-weight: 600;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-bg-subtle);
    color: var(--sw-text-secondary);
}

.sw-tab-active .sw-tab-count {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
}

/* ── Rating dots ── */

.sw-rating-good {
    background: var(--sw-success);
}

.sw-rating-moderate {
    background: var(--sw-warning);
}

.sw-rating-poor {
    background: var(--sw-danger);
}

/* Neutral dot for "not yet measured" - distinct from red/green/amber. */
.sw-rating-neutral {
    background: var(--sw-text-muted);
}

/* #949: the traffic light next to a value - three lamps, one lit (sw_light() in Twig,
   assets/traffic_light.js for polled values). It replaced the single rating dot on
   every surface. Colour never stands alone: only the lit lamp is filled and glows,
   the light names its state, and a row carries the same band in border and chip. */
.sw-light { display: inline-flex; align-items: center; vertical-align: middle; margin-right: .35rem; gap: 4px; padding: 4px 6px; border-radius: var(--sw-radius-btn); background: rgba(8, 12, 20, 0.55); border: 1px solid rgba(143, 163, 187, 0.22); }
.sw-light i { display: block; width: 9px; height: 9px; border-radius: 50%; background: rgba(143, 163, 187, 0.14); border: 1px solid rgba(143, 163, 187, 0.26); }
.sw-light--poor i:nth-child(1) { background: var(--sw-danger); border-color: transparent; box-shadow: 0 0 6px rgba(239, 68, 68, 0.55); }
.sw-light--moderate i:nth-child(2) { background: var(--sw-warning); border-color: transparent; box-shadow: 0 0 6px rgba(245, 158, 11, 0.55); }
.sw-light--good i:nth-child(3) { background: var(--sw-success); border-color: transparent; box-shadow: 0 0 6px rgba(34, 197, 94, 0.5); }
.sw-result-panel__check--moderate { border-color: rgba(245, 158, 11, 0.32); }
.sw-result-panel__cnt--moderate { color: var(--sw-warning); border-color: rgba(245, 158, 11, 0.32); background: rgba(245, 158, 11, 0.10); }
.sw-light--neutral i { background: rgba(143, 163, 187, 0.14); }
.sw-result-panel__status .sw-light, .sw-av2-card__rating .sw-light { margin-right: 0; }
.sw-av2-card__rating .sw-light { margin-right: .4rem; }

/* ── Metric info box ── */

.sw-md-description p {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.6;
    margin-bottom: 1rem;
}

.sw-table-compact {
    font-size: var(--sw-text-sm);
}

.sw-table-compact th,
.sw-table-compact td {
    padding: 0.5rem 0.75rem;
}

/* ── Code snippet ── */

/* ── Impersonation banner ── */

.sw-impersonation-banner {
    background: #fbbf24;
    color: #1a1a1a;
    text-align: center;
    padding: 0.5rem 1rem;
    font-size: var(--sw-text-base);
    font-weight: 500;
}

.sw-impersonation-banner a {
    color: #1a1a1a;
    font-weight: 600;
    text-decoration: underline;
    margin-left: 0.75rem;
}

.sw-impersonation-banner a:hover {
    color: #111827;
}

/* ── Queue stats ── */

/* ── ShopWatch Score Hero ── */

/* ── Lead page ── */

.sw-lead-wrapper {
    max-width: 560px;
    margin: 0 auto;
    padding: 4rem 0 3rem;
    text-align: center;
}

.sw-lead-heading {
    font-size: 2.25rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin-bottom: 0.75rem;
}

.sw-lead-sub {
    font-size: var(--sw-text-xl);
    color: var(--sw-text-secondary);
    margin-bottom: 2rem;
    line-height: 1.6;
}

.sw-lead-wrapper .sw-card {
    text-align: left;
}

.sw-lead-hint {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    margin-top: 1.25rem;
}

.sw-lead-results {
    max-width: 960px;
    margin: 0 auto;
    padding: 2.5rem 0 3rem;
}

.sw-lead-results h1 {
    font-size: var(--sw-text-4xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin-bottom: 0.25rem;
}

.sw-lead-cta {
    text-align: center;
    margin-top: 3rem;
    padding: 3rem 2rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
}

.sw-lead-cta h2 {
    font-size: var(--sw-text-3xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin-bottom: 0.5rem;
}

.sw-lead-cta p {
    font-size: var(--sw-text-lg);
    color: var(--sw-text-secondary);
    margin-bottom: 1.5rem;
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
}

/* ── Ranking (shared base: list rows, scores, medals) ──
   Layout/podium/delta styling lives in the "Ranking (redesign)" block below. */

/* ── Skeleton loading ── */

@keyframes sw-skeleton-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

.sw-skeleton {
    display: inline-block;
    background: var(--sw-border);
    border-radius: var(--sw-radius-sm);
    animation: sw-skeleton-pulse 1.5s ease-in-out infinite;
}

/* ── Modal ── */

.sw-modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    padding: 1rem;
    animation: sw-overlay-in 0.18s ease-out;
}

@keyframes sw-overlay-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.sw-modal-overlay[hidden] {
    display: none;
}

.sw-modal {
    position: relative;
    background: var(--sw-surface);
    border-radius: var(--sw-radius-card);
    padding: 2rem;
    max-width: 480px;
    width: 100%;
    text-align: left;
    box-shadow: var(--sw-shadow-modal);
    animation: sw-modal-in 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes sw-modal-in {
    from { opacity: 0; transform: scale(0.96) translateY(6px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

/* Terms modal keeps centred text (was the global default before) */

.sw-modal-header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.sw-modal-header .sw-modal-icon {
    margin-bottom: 1rem;
}

.sw-modal-header p {
    margin-bottom: 0;
}

.sw-modal-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    background: none;
    border: none;
    color: var(--sw-text-muted);
    cursor: pointer;
    padding: 0.5rem;
    /* #649: a 44px hit area around the 20px icon */
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sw-radius-sm);
    transition: color 0.15s, background 0.15s;
}

.sw-modal-close:hover {
    color: var(--sw-text);
    background: var(--sw-bg-subtle);
}

.sw-modal-close:focus-visible {
    outline: 2px solid var(--sw-brand-text);
    outline-offset: 2px;
}

.sw-modal-close svg {
    width: 20px;
    height: 20px;
}

.sw-modal-icon {
    width: 48px;
    height: 48px;
    border-radius: var(--sw-radius-card);
    background: var(--sw-brand-tint);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.25rem;
}

.sw-modal-icon svg {
    width: 24px;
    height: 24px;
    color: var(--sw-brand-text);
}

.sw-modal h3 {
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin-bottom: 0.5rem;
}

.sw-modal p {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.6;
    margin-bottom: 1.5rem;
}

.sw-modal-field {
    margin-bottom: 1rem;
}

.sw-modal-field:last-of-type {
    margin-bottom: 0;
}

.sw-modal form textarea.sw-form-control {
    resize: vertical;
    min-height: 6rem;
}

.sw-modal-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.sw-modal-actions .sw-btn {
    justify-content: center;
}

/* Feedback modal: full-width stacked buttons */
#feedback-modal-root .sw-modal-actions .sw-btn {
    width: 100%;
}

/* Submit loading state */
.sw-btn-primary[data-loading="true"] {
    opacity: 0.7;
    cursor: wait;
    position: relative;
}

.sw-btn-primary[data-loading="true"]::after {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-top-color: #fff;
    border-radius: 50%;
    animation: sw-btn-spin 0.6s linear infinite;
    margin-left: 0.5rem;
    vertical-align: middle;
}

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

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .sw-modal-overlay {
        animation: none;
    }

    .sw-modal {
        animation: none;
    }

    .sw-btn-primary[data-loading="true"]::after {
        animation: none;
        opacity: 0.5;
    }

}

/* Mobile bottom-sheet */
@media (max-width: 575.98px) {
    .sw-modal-overlay {
        align-items: flex-end;
        padding: 0;
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }

    .sw-modal {
        border-radius: var(--sw-radius-card) var(--sw-radius-card) 0 0;
        max-width: 100%;
        width: 100%;
        padding: 1.5rem 1.25rem 2rem;
        animation: sw-modal-in-sheet 0.22s cubic-bezier(0.16, 1, 0.3, 1);
    }

    @keyframes sw-modal-in-sheet {
        from { opacity: 0; transform: translateY(20px); }
        to { opacity: 1; transform: translateY(0); }
    }

    @media (prefers-reduced-motion: reduce) {
        .sw-modal {
            animation: none;
        }
    
    }

}

/* ── Metric Tiles ── */

/* ── CTA Note ── */

/* ── Scroll Reveal Animations ── */

/* Scroll reveal (#651): visible by default - the controller adds
   `sw-reveal-pending` in connect() to the elements it will animate, so a
   lazy controller that never loads (the Traefik 429 incident) or JS-off keeps
   every section on screen. */
.sw-reveal {
    transition: opacity 0.7s ease, transform 0.7s ease;
}

.sw-reveal.sw-reveal-pending {
    opacity: 0;
}

.sw-reveal-pending.sw-reveal-up {
    transform: translateY(32px);
}

.sw-revealed {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .sw-reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

}

/* Always-dark sections: brand-colored text uses the lighter emerald for AA
   contrast on their dark backgrounds, regardless of the active page theme.
   --sw-brand-tint is re-pinned here too: it's a light/dark-reactive token
   (#EFF6FF light / rgba(59,130,246,.14) dark) that otherwise stays near-white
   in these always-dark sections while the site is in light mode - breaking
   contrast for anything drawn on top of it (e.g. .sw-card-icon, the audience
   "agency" panel below). */
.sw-hero-wrapper,
.sw-cta-dark {
    --sw-brand-text: var(--sw-brand-light);
    --sw-brand-tint: rgba(59, 130, 246, 0.14);
}

/* ── Hero Wrapper (dark) ── */

.sw-hero-wrapper {
    background: var(--sw-dark-bg-subtle); /* #647: a tinted band, not the page colour again */
    position: relative;
    overflow: hidden;
    min-height: calc(100vh - 68px);
    display: flex;
    flex-direction: column;
}
@keyframes sw-hero-bloom-pulse {
    0%, 100% { opacity: 0.55; transform: translate(-50%, -55%) scale(1); }
    50%      { opacity: 0.78; transform: translate(-50%, -55%) scale(1.08); }
}
@keyframes sw-hero-bloom-drift-a {
    0%, 100% { transform: translate(0, 0); }
    50%      { transform: translate(-50px, 40px); }
}
@keyframes sw-hero-bloom-drift-b {
    0%, 100% { transform: translate(0, 0); }
    50%      { transform: translate(50px, -30px); }
}

.sw-hero-wrapper > .container {
    position: relative;
    z-index: 1;
}
/* First content container - on the home page the aurora div sits before it, so
   :first-child alone would miss it (hero grid lost flex: 1, trust bar floated mid-page). */
.sw-hero-wrapper > .container:first-child {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.sw-hero-wrapper .sw-hero {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 4rem 0;
}

.sw-hero-wrapper .sw-hero h1 {
    color: #fff;
}

.sw-hero-wrapper .sw-hero .sw-hero-sub {
    color: var(--sw-dark-text-secondary);
}

.sw-hero-wrapper .sw-btn-outline {
    color: var(--sw-dark-text-secondary) !important;
    border-color: var(--sw-dark-border);
}

.sw-hero-wrapper .sw-btn-outline:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff !important;
    border-color: #4b5563;
}

/* ── Section Dividers ── */

/* Section dividers (#647): the clip-path wedges painted --sw-dark-bg onto --sw-bg,
   which are the same colour on the dark-only site - a 80px band of nothing. The
   rhythm now comes from tinted bands (hero and CTA on --sw-dark-bg-subtle, content
   on --sw-bg) and this hairline. Variant classes stay for the templates. */
.sw-section-divider,
.sw-section-divider--to-light,
.sw-section-divider--to-dark {
    height: 0;
    position: relative;
    background: transparent;
    border-top: 1px solid var(--sw-border);
}
.sw-section-divider--to-light::after,
.sw-section-divider--to-dark::after {
    content: none;
}

/* ── Feature Tabs ── */

.sw-feature-tabs {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-bottom: 3rem;
    flex-wrap: wrap;
}

.sw-feature-tab {
    padding: 0.625rem 1.5rem;
    font-size: var(--sw-text-md);
    font-weight: 500;
    color: var(--sw-text-secondary);
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    cursor: pointer;
    transition: background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
}

.sw-feature-tab:hover {
    color: var(--sw-text);
    border-color: #d1d5db;
}

.sw-feature-tab:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
}

.sw-feature-tab.sw-tab-active {
    background: var(--sw-brand-strong);
    color: #fff;
    border-color: var(--sw-brand-text);
    box-shadow: 0 2px 8px rgba(59, 130, 246, 0.25);
}

/* ── CTA Dark (merged stats + CTA) ── */

.sw-cta-dark {
    background: var(--sw-dark-bg-subtle); /* #647: a tinted band, not the page colour again */
    position: relative;
    overflow: hidden;
}

.sw-cta-dark::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 140%;
    height: 140%;
    transform: translate(-50%, -50%);
    background: radial-gradient(ellipse at center, rgba(59, 130, 246, 0.1) 0%, transparent 60%);
    pointer-events: none;
}

.sw-cta-dark .sw-section-heading {
    color: #fff;
}

.sw-cta-dark .sw-section-sub {
    color: var(--sw-dark-text-secondary);
}

.sw-cta-dark .sw-btn-outline {
    color: var(--sw-dark-text-secondary) !important;
    border-color: var(--sw-dark-border);
}

.sw-cta-dark .sw-btn-outline:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff !important;
    border-color: #4b5563;
}

/* ── Responsive ── */

/* Below the hamburger breakpoint the account area has ONE navigation (#1108): the
   links live in the hamburger (account/_nav_links.html.twig, rendered by the
   navbar), so the sidebar keeps only its context pickers. Same 1100px as the
   top navigation, so no width shows two navigations at once. */
@media (max-width: 1099.98px) {
    .sw-app-layout {
        /* minmax(0, 1fr) - NOT bare 1fr (= minmax(auto,1fr)), which lets the
           column blow out to the widest child's intrinsic width (e.g. the
           nowrap analytics sub-nav ~950px) and overflow the viewport. */
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
        padding-top: 1.5rem;
    }

    .sw-sidebar {
        position: static;
        min-height: auto;
    }

    .sw-sidebar-nav,
    .sw-sidebar-footer {
        display: none;
    }
}

@media (max-width: 767.98px) {
    .sw-hero h1 {
        font-size: 2.25rem;
    }

    .sw-hero .sw-hero-sub {
        font-size: var(--sw-text-xl);
    }

    .sw-hero {
        padding: 3rem 0 2rem;
    }

    .sw-section {
        padding: 3rem 0;
    }

    .sw-section-heading {
        font-size: var(--sw-text-3xl);
    }

    .sw-btn-primary, .sw-btn-outline {
        width: 100%;
        justify-content: center;
        margin-top: 0.5rem;
    }

    .sw-shop-form-row {
        flex-direction: column;
        align-items: stretch;
    }

    .sw-workspace-summary {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.875rem;
    }

    .sw-lead-wrapper {
        padding: 2.5rem 0 2rem;
    }

    .sw-lead-heading {
        font-size: var(--sw-text-4xl);
    }

    .sw-hero-wrapper .sw-hero {
        padding: 2rem 0;
    }

    .sw-section-divider {
        height: 0;
    }

    .sw-feature-tabs {
        gap: 0.375rem;
    }

    .sw-feature-tab {
        padding: 0.5rem 1.125rem;
        font-size: var(--sw-text-sm);
    }

}

/* ── Code Block (markup findings) ── */
.sw-code-block {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    overflow: hidden;
    overflow-x: auto;
    background: var(--sw-bg-subtle);
}

/* Fallback plain-text code block (no syntax highlighting) - dark-mode safe. */
.sw-code-pre {
    margin: 0.75rem 0 0;
    padding: 0.75rem 1rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    font-size: var(--sw-text-sm);
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--sw-text-secondary);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

.sw-code-wrapper {
    display: flex;
    overflow-x: auto;
    scrollbar-width: thin;
}

.sw-code-wrapper pre {
    margin: 0;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    font-size: var(--sw-text-sm);
    line-height: 1.7;
    padding: 0.75rem 0;
}

.sw-code-gutter {
    flex-shrink: 0;
    padding-left: 0.75rem !important;
    padding-right: 0.75rem !important;
    text-align: right;
    color: #8b949e;
    background: #f6f8fa;
    border-right: 1px solid var(--sw-border);
    user-select: none;
}

.sw-code-content {
    flex: 1;
    min-width: 0;
    padding-left: 1rem !important;
    padding-right: 1rem !important;
    background: #ffffff;
}

.sw-code-content code {
    background: none !important;
    padding: 0 !important;
    font-size: inherit !important;
}

/* Per-line highlighting (applied by JS after hljs runs) */
.sw-code-line-highlight {
    display: inline-block;
    width: calc(100% + 2rem);
    margin: 0 -1rem;
    padding: 0 1rem;
    background: #fff8c5;
}

.sw-code-gutter-highlight {
    display: inline-block;
    width: calc(100% + 1.5rem);
    margin: 0 -0.75rem;
    padding: 0 0.75rem;
    background: #ede7b2;
    color: var(--sw-text);
    font-weight: 600;
    text-align: right;
}

/* Override highlight.js background */
.sw-code-block .hljs {
    background: transparent !important;
    padding: 0 !important;
}

/* ── Shop Overview List (Dashboard) ── */

/* ── Shop Card (Dashboard Score Ring) ── */

/* ── Roadmap ── */

/* Content page hero (generic, used by roadmap, performance, seo, trust, best-practices) */

.sw-content-hero,
.sw-roadmap-hero {
    min-height: auto;
}

.sw-content-hero > .container:first-child,
.sw-roadmap-hero > .container:first-child {
    flex: 0;
}

.sw-content-hero .sw-hero,
.sw-roadmap-hero .sw-hero {
    flex: 0;
    padding: 5rem 0 3rem;
}

/* Timeline */

.sw-timeline {
    position: relative;
    padding-left: 2rem;
}

.sw-timeline::before {
    content: '';
    position: absolute;
    left: 7px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--sw-border);
}

.sw-timeline-item {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
    padding-bottom: 2.5rem;
}

.sw-timeline-item:last-child {
    padding-bottom: 0;
}

.sw-timeline-marker {
    position: absolute;
    left: -2rem;
    top: 1.75rem;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--sw-bg);
    border: 2px solid var(--sw-border);
    z-index: 1;
    flex-shrink: 0;
    transform: translateX(-0.5px);
}

.sw-timeline-marker--active {
    background: var(--sw-success);
    border-color: var(--sw-success);
    box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.15);
}

.sw-timeline-content {
    flex: 1;
    min-width: 0;
}

.sw-timeline-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.sw-timeline-header h3 {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    margin: 0;
    color: var(--sw-text);
}

.sw-timeline-badge { white-space: nowrap; }

/* Roadmap list */

.sw-roadmap-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.sw-roadmap-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.5;
}

.sw-roadmap-item--completed {
    color: var(--sw-text);
}

.sw-roadmap-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--sw-success);
    margin-top: 1px;
}

/* #682: the check mark is drawn here, not as an inline SVG per item (25 copies on one page). */
.sw-roadmap-check::before {
    content: '';
    display: block;
    width: 6px;
    height: 11px;
    margin-top: -3px;
    border: solid currentColor;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.sw-roadmap-circle {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--sw-border);
    flex-shrink: 0;
    margin-top: 7px;
    margin-left: 6px;
    margin-right: 6px;
}

/* Roadmap dark mode */

html.sw-dark .sw-timeline-badge {
    background: rgba(59, 130, 246, 0.15);
    border-color: rgba(59, 130, 246, 0.25);
}

html.sw-dark .sw-timeline-marker {
    background: var(--sw-bg-subtle);
}

html.sw-dark .sw-feature-tab:hover {
    border-color: #4b5563;
}

/* Roadmap responsive */

@media (max-width: 767.98px) {
    .sw-content-hero .sw-hero,
    .sw-roadmap-hero .sw-hero {
        padding: 3rem 0 2rem;
    }

    .sw-timeline {
        padding-left: 0;
    }

    .sw-timeline::before {
        display: none;
    }

    .sw-timeline-marker {
        display: none;
    }

    .sw-timeline-item {
        gap: 0;
        padding-bottom: 1.5rem;
    }

}

/* ── Roadmap - momentum stats, statuses & legend ── */

/* Hero stat bar (dark hero) */
/* #849: die Reihe bleibt zentriert, die Kacheln darin sind Fließtext geworden. */
.sw-roadmap-stats { margin-top: 2.5rem; }

.sw-roadmap-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
}

.sw-roadmap-stat-num {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    color: #fff;
}

.sw-roadmap-stat-num--live {
    color: var(--sw-brand-light);
}

/* Legend */
.sw-roadmap-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.5rem;
    margin: -1.5rem 0 2.5rem;
}

.sw-roadmap-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-secondary);
}

.sw-roadmap-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.sw-roadmap-legend-dot--shipped { background: var(--sw-success); }
.sw-roadmap-legend-dot--progress { background: var(--sw-brand); }
.sw-roadmap-legend-dot--planned { background: var(--sw-border); }

/* Version tag in the release header */
.sw-roadmap-version {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    padding: 0.125rem 0.5rem;
    font-size: var(--sw-text-2xs);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--sw-text-muted);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-sm);
    white-space: nowrap;
}

/* Shipped / in-progress item text emphasis */
.sw-roadmap-item--shipped .sw-roadmap-item-text {
    color: var(--sw-text);
}

.sw-roadmap-item--in_progress .sw-roadmap-item-text {
    color: var(--sw-text);
    font-weight: 500;
}

/* In-progress marker (pulsing brand) */
.sw-timeline-marker--progress {
    background: var(--sw-brand);
    border-color: var(--sw-brand-text);
    animation: sw-roadmap-pulse 2s ease-in-out infinite;
}

/* In-progress item dot */
.sw-roadmap-pulse {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--sw-brand);
    flex-shrink: 0;
    margin: 7px 6px 0;
    animation: sw-roadmap-pulse 2s ease-in-out infinite;
}

@keyframes sw-roadmap-pulse {
    0%, 100% { box-shadow: 0 0 0 2px var(--sw-focus-ring); }
    50% { box-shadow: 0 0 0 7px rgba(59, 130, 246, 0.05); }
}

/* "In progress" tag pill */
.sw-roadmap-tag {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    margin-left: 0.5rem;
    white-space: nowrap;
    flex-shrink: 0;
}

/* Roadmap new components - dark mode */
html.sw-dark .sw-roadmap-tag {
    background: rgba(59, 130, 246, 0.18);
}

/* Roadmap new components - responsive */
@media (max-width: 767.98px) {
    .sw-roadmap-stats {
        gap: 1.5rem 2rem;
        margin-top: 2rem;
    }

    .sw-roadmap-stat-num {
        font-size: var(--sw-text-3xl);
    }

    .sw-roadmap-legend {
        gap: 1rem;
        margin: -1rem 0 2rem;
    }

    .sw-roadmap-version {
        margin-left: 0;
    }

}

@media (prefers-reduced-motion: reduce) {
    .sw-timeline-marker--progress,
    .sw-roadmap-pulse {
        animation: none;
    }

}

/* ── Content Pages ── */

.sw-content-card {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.sw-content-card-title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    margin: 0.75rem 0 0.5rem;
    color: var(--sw-text);
}

.sw-content-card-text {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.6;
    margin: 0;
    flex: 1;
}


.sw-content-info {
    background: var(--sw-bg-subtle);
    border: 1px dashed var(--sw-border);
}

.sw-content-info .sw-content-card-title {
    font-size: var(--sw-text-2xl);
}

.sw-content-info .sw-content-card-text {
    font-size: var(--sw-text-lg);
}

/* ── Check Management ── */

.sw-check-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.875rem 1rem;
    border-bottom: 1px solid var(--sw-border);
}

.sw-check-item:last-child {
    border-bottom: none;
}

.sw-check-item-info {
    flex: 1;
    min-width: 0;
}

.sw-check-item-header {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
}

.sw-check-item-name {
    font-weight: 600;
    font-size: var(--sw-text-md);
    color: var(--sw-text);
}

.sw-check-item-description {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin-top: 0.25rem;
}

/* ── Uptime split-timeline ── */

.sw-uptime-split {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 1.5rem;
    align-items: start;
}

@media (max-width: 991.98px) {
    .sw-uptime-split {
        grid-template-columns: 1fr;
    }

}

.sw-uptime-side {
    display: flex;
    flex-direction: column;
}

.sw-uptime-side-card {
    margin-bottom: 1.25rem;
}

.sw-uptime-side-card:last-child {
    margin-bottom: 0;
}

/* ── Left column: status card ── */
.sw-uptime-status-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 0.125rem;
}

.sw-uptime-status-dot {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    flex-shrink: 0;
}

.sw-uptime-status-dot--up {
    background: var(--sw-success);
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
}

.sw-uptime-status-dot--up_protected {
    background: var(--sw-warning);
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.18);
}

.sw-uptime-status-dot--down {
    background: var(--sw-danger);
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.18);
}

.sw-uptime-status-dot--unknown {
    background: var(--sw-text-muted);
}

.sw-uptime-side-domain {
    font-size: var(--sw-text-lg);
    font-weight: 700;
    color: var(--sw-text);
    word-break: break-all;
    line-height: 1.3;
}

.sw-uptime-side-statustext {
    font-size: var(--sw-text-sm);
    font-weight: 600;
}

.sw-uptime-side-statustext--up {
    color: var(--sw-success-text);
}

.sw-uptime-side-statustext--up_protected {
    color: var(--sw-warning-text);
}

.sw-uptime-side-statustext--down {
    color: var(--sw-poor-text);
}

.sw-uptime-side-statustext--unknown {
    color: var(--sw-text-muted);
}

.sw-uptime-side-stat-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: 1.125rem;
    padding-top: 1.125rem;
    border-top: 1px solid var(--sw-border);
}



.sw-uptime-side-meta {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin-top: 0.625rem;
}

/* ── Left column: SSL card ── */
.sw-uptime-ssl-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.sw-uptime-ssl-icon {
    width: 36px;
    height: 36px;
    border-radius: var(--sw-radius-inline);
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.sw-uptime-ssl-icon svg {
    width: 19px;
    height: 19px;
}

.sw-uptime-ssl-icon--warn {
    background: var(--sw-warning-tint);
    color: var(--sw-warning-text);
}

.sw-uptime-ssl-icon--danger {
    background: var(--sw-danger-tint);
    color: var(--sw-danger-dark);
}

.sw-uptime-ssl-days {
    font-size: var(--sw-text-md);
    font-weight: 700;
    color: var(--sw-text);
}

.sw-uptime-ssl-days--warn {
    color: var(--sw-warning-text);
}

.sw-uptime-ssl-days--danger {
    color: var(--sw-danger-dark);
}

.sw-uptime-ssl-sub {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
}

/* ── Left column: plan card (doubles as the Free-plan history upsell) ── */
.sw-uptime-plan-card--upsell {
    background: var(--sw-brand-tint);
    border-color: rgba(59, 130, 246, 0.25);
}

.sw-uptime-plan-title {
    font-size: var(--sw-text-sm);
    font-weight: 700;
    color: var(--sw-text);
    margin: 0 0 0.625rem;
}

.sw-uptime-plan-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    display: flex;
    flex-direction: column;
    gap: 0.4375rem;
}

.sw-uptime-plan-list li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.sw-uptime-plan-list li.locked {
    color: var(--sw-text-muted);
}

.sw-uptime-plan-list svg {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

.sw-uptime-plan-list li:not(.locked) svg {
    color: var(--sw-success);
}

.sw-uptime-plan-list li.locked svg {
    color: var(--sw-text-muted);
}

.sw-uptime-plan-cta {
    width: 100%;
    justify-content: center;
}

/* ── Right column: history card head ── */
.sw-uptime-history-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.25rem;
}

.sw-uptime-history-title {
    font-size: var(--sw-text-lg);
    font-weight: 700;
    color: var(--sw-text);
    margin: 0;
}

.sw-uptime-history-sub {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin: 0.125rem 0 0;
}
.sw-uptime-live-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-success-text);
}

.sw-uptime-live-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--sw-success);
    animation: sw-uptime-pulse 1.6s ease-in-out infinite;
}

.sw-uptime-subsection {
    margin-top: 1.375rem;
}

.sw-uptime-subsection + .sw-uptime-subsection {
    margin-top: 1.5rem;
    padding-top: 1.375rem;
    border-top: 1px solid var(--sw-border);
}

.sw-uptime-subsection-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.625rem;
}

.sw-uptime-subsection-cap {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin: 0.625rem 0 0;
}

/* ── Uptime bar (JS targets preserved) ── */
.sw-uptime-bar {
    position: relative;
}

.sw-uptime-bar-track {
    display: flex;
    gap: 2px;
    height: 36px;
    border-radius: var(--sw-radius-sm);
    overflow: hidden;
}

.sw-uptime-bar-segment {
    flex: 1;
    min-width: 0;
    border-radius: 2px;
    cursor: pointer;
    transition: opacity 80ms ease, transform 80ms ease;
    transform-origin: center;
}

@media (hover: hover) and (pointer: fine) {
    .sw-uptime-bar-segment:hover {
        opacity: 0.75;
        transform: scaleY(1.08);
    }

    .sw-uptime-bar-segment:active {
        transform: scaleY(0.95);
    }

}

.sw-uptime-bar-ok {
    background: var(--sw-success);
}

.sw-uptime-bar-minor {
    background: var(--sw-warning);
}

.sw-uptime-bar-major {
    background: var(--sw-danger);
}

.sw-uptime-bar-no_data {
    background: var(--sw-border);
    opacity: 0.45;
}

.sw-uptime-bar-labels {
    display: flex;
    justify-content: space-between;
    margin-top: 0.375rem;
    font-size: var(--sw-text-2xs);
    color: var(--sw-text-muted);
    letter-spacing: 0.02em;
}

/* ── Tooltip (JS-controlled display:block) ── */
.sw-uptime-bar-tooltip {
    display: none;
    position: absolute;
    bottom: calc(100% + 8px);
    background: var(--sw-footer-bg);
    color: #fff;
    padding: 0.5rem 0.75rem;
    border-radius: var(--sw-radius-control);
    font-size: var(--sw-text-xs);
    line-height: 1.5;
    white-space: nowrap;
    z-index: 10;
    pointer-events: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.sw-uptime-tooltip-status {
    font-weight: 600;
}

.sw-uptime-tooltip-ok {
    color: var(--sw-success);
}

.sw-uptime-tooltip-minor {
    color: var(--sw-warning);
}

.sw-uptime-tooltip-major {
    color: var(--sw-danger);
}

.sw-uptime-bar-wrap {
    margin: 0 0 0.625rem;
}

.sw-uptime-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin: 0.75rem 0 0;
    font-size: var(--sw-text-xs);
    color: var(--sw-text-secondary);
}

.sw-uptime-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

.sw-uptime-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    flex-shrink: 0;
}

/* ── Timeline spine: a single connected line running from the live "Now"
   node down through the incident history ── */
/* The incident list has its own card below the two columns (#821), so it no
   longer needs the divider that separated it from the bars above it. */
.sw-uptime-incidents-card {
    margin-top: var(--sw-space-5);
}

/* .sw-card sets height: 100%, which in a grid resolves against the row - and
   the row is as tall as the taller status column. With the incident list gone
   the history card would end in a screen of empty space (#821). */
.sw-uptime-history-card {
    height: auto;
}

.sw-uptime-spine-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    border-left: 2px solid var(--sw-border);
    margin-left: 6px;
    padding-left: 1.25rem;
}

.sw-uptime-spine-now {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0 0 1.25rem;
    position: relative;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-uptime-spine-now b {
    color: var(--sw-text);
    font-weight: 600;
}

.sw-uptime-spine-now-dot {
    position: absolute;
    left: -1.625rem;
    top: 0.2rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--sw-success);
    border: 2px solid var(--sw-bg);
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
}

.sw-uptime-incident {
    display: flex;
    align-items: flex-start;
    gap: 0;
    padding: 0.75rem 0;
    position: relative;
}

.sw-uptime-incident-dot {
    position: absolute;
    left: -1.625rem;
    top: 1rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
    border: 2px solid var(--sw-bg);
}

.sw-uptime-incident-dot--warning {
    background: var(--sw-warning);
    box-shadow: 0 0 0 3px var(--sw-warning-tint);
}

.sw-uptime-incident-dot--critical {
    background: var(--sw-danger);
    box-shadow: 0 0 0 3px var(--sw-danger-tint);
}

.sw-uptime-incident-content {
    flex: 1;
    min-width: 0;
}

.sw-uptime-incident-row-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.sw-uptime-incident-row-head-left {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    flex-wrap: wrap;
}

.sw-uptime-severity {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: var(--sw-text-2xs);
    font-weight: 700;
    padding: 0.1rem 0.5rem;
    border-radius: var(--sw-radius-btn);
    letter-spacing: 0.02em;
    flex-shrink: 0;
}

.sw-uptime-severity--critical {
    background: var(--sw-danger-tint);
    color: var(--sw-poor-text);
}

.sw-uptime-severity--warning {
    background: var(--sw-warning-tint);
    color: var(--sw-warning-text);
}

.sw-uptime-incident-label {
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
}

.sw-uptime-duration-badge {
    font-size: var(--sw-text-xs);
    font-weight: 700;
    color: var(--sw-text);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    padding: 0.15rem 0.625rem;
    white-space: nowrap;
    flex-shrink: 0;
}

.sw-uptime-incident-time {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    margin-top: 0.125rem;
}

/* Live "now" indicator: the most recent segment (today) breathes to signal
   that monitoring is current. No entrance animation - the bar is data, not a
   reveal. Opacity-only (the track is overflow:hidden, so a glow would clip). */
@keyframes sw-uptime-pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.4;
    }
}

.sw-uptime-bar-segment--current {
    animation: sw-uptime-pulse 1.6s ease-in-out infinite;
}

/* Deep-link target: the 403 page sends plan-gated users to /pricing#agency, so
   the Agency card lands cleanly below the sticky navbar instead of behind it. */
#agency {
    scroll-margin-top: calc(var(--sw-navbar-height) + 12px);
}

@media (prefers-reduced-motion: reduce) {
    .sw-uptime-bar-segment--current {
        animation: none;
    }

    .sw-uptime-bar-segment {
        transition: none;
    }

}

/* ── Uptime mobile: single-column stack (side cards above the history card,
   already handled by .sw-uptime-split's breakpoint) plus tighter spacing ── */
@media (max-width: 767.98px) {
    .sw-uptime-incident-row-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }

}

@media (max-width: 575.98px) {
    .sw-uptime-side-card,
    .sw-uptime-history-card {
        padding: 1.25rem;
    }

    .sw-uptime-side-stat-num {
        font-size: var(--sw-text-3xl);
    }

    /* Hide "· R12" issuer - too narrow, low value */

    .sw-uptime-incident-time {
        font-size: var(--sw-text-xs);
    }

}

/* ── Worker Heartbeat ── */

/* ── Pricing ── */

.sw-pricing-hero {
    min-height: auto;
}

/* The plan-decision area used to be squeezed until hero, three plans and the
   trust row fit one screen. That bought a scroll-free page at the price of a
   cramped opening (founder review 2026-09-04). The page now breathes: the
   headline gets room, the promise gets a readable measure, and the cards get
   their own air. Everything still lands within about one and a half screens on
   a laptop, so the decision is never far away. FAQ + CTA stay below. */
.sw-pricing-hero .sw-hero {
    flex: 0;
    padding: 4rem 0 2.75rem;
}
.sw-pricing-hero .sw-hero h1 {
    font-size: 2.5rem;
}
.sw-pricing-hero .sw-hero .sw-hero-sub {
    /* Wider than the global 600px: this promise is one long sentence and broke
       into five short lines, which reads as a column of fragments. */
    max-width: 44rem;
    margin-top: 1rem;
    margin-bottom: 0;
}
/* On a phone the roomier headline would eat the first screen on its own. */
@media (max-width: 767.98px) {
    .sw-pricing-hero .sw-hero {
        padding: 2.5rem 0 1.75rem;
    }
    .sw-pricing-hero .sw-hero h1 {
        font-size: var(--sw-text-5xl);
    }
    .sw-pricing-plans {
        padding-top: 2rem;
        padding-bottom: 3rem;
    }
}
/* Shorter angled transition - the full 80px divider is wasteful here. */
.sw-pricing-hero + .sw-section-divider {
    height: 0;
}
.sw-pricing-plans {
    padding-top: 3rem;
    padding-bottom: 4.5rem;
}
.sw-pricing-plans .sw-billing-toggle {
    margin-bottom: 2.25rem;
}
.sw-pricing-plans .sw-pricing-card {
    padding: 1.75rem 1.75rem;
}
.sw-pricing-plans .sw-pricing-amount {
    font-size: var(--sw-text-5xl);
}
.sw-pricing-plans .sw-pricing-card--featured {
    transform: scale(1.02);
}
.sw-pricing-plans .sw-pricing-card--featured:hover {
    transform: scale(1.02) translateY(-2px);
}
.sw-pricing-plans .sw-pricing-tier {
    margin-bottom: 0.5rem;
}
.sw-pricing-plans .sw-pricing-price {
    margin-bottom: 0.375rem;
}
.sw-pricing-plans .sw-pricing-tagline {
    margin-bottom: 0.875rem;
}
.sw-pricing-plans .sw-pricing-includes {
    margin-bottom: 0.5rem;
}
.sw-pricing-plans .sw-pricing-features {
    margin-bottom: 0.875rem;
}
.sw-pricing-plans .sw-pricing-features li {
    margin-bottom: 0.4375rem;
    font-size: var(--sw-text-base);
}
.sw-pricing-plans .sw-pricing-trust {
    margin-top: 2.25rem;
}

.sw-pricing-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.5rem;
    align-items: stretch;
}

.sw-pricing-card {
    position: relative;
    background: var(--sw-surface);
    border: 1px solid var(--sw-border-strong);
    border-radius: var(--sw-radius-card);
    padding: var(--sw-card-pad-lg);
    display: flex;
    flex-direction: column;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.sw-pricing-card:hover {
    box-shadow: var(--sw-shadow-md);
    transform: translateY(-2px);
}

.sw-pricing-popular {
    position: absolute;
    top: -0.75rem;
    left: 50%;
    transform: translateX(-50%);
    background: var(--sw-brand-strong); /* #648: white text needs the strong blue (6.7:1) */
    color: #fff;
    font-size: var(--sw-text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.25rem 0.75rem;
    border-radius: var(--sw-radius-btn);
    white-space: nowrap;
}

.sw-pricing-tier {
    font-size: var(--sw-text-base);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sw-text-secondary);
    margin-bottom: 0.75rem;
}

.sw-pricing-price {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
    margin-bottom: 0.75rem;
}

.sw-pricing-amount {
    font-size: 2.5rem;
    font-weight: 700;
    color: var(--sw-text);
    letter-spacing: -0.02em;
}

.sw-pricing-period {
    font-size: var(--sw-text-lg);
    color: var(--sw-text-secondary);
    white-space: nowrap;
}

/* #953 P-08: strike price and saving pill sit on their own line under the price. */
.sw-pricing-price { flex-wrap: wrap; }
.sw-pricing-yearly { flex-basis: 100%; display: flex; align-items: center; gap: .5rem; min-height: 1.75rem; }
/* Monthly mode: the wrapper holds only hidden parts and must not add an empty line. */
.sw-pricing-yearly:not(:has(> :not([hidden]))) { display: none; }

.sw-pricing-tagline {
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-md);
    margin-bottom: 1.5rem;
    min-height: 3.2em; /* #953 P-12: two lines (line-height 1.6) reserved, the three buttons line up */
}

.sw-pricing-features {
    list-style: none;
    padding: 0;
    margin: 0 0 2rem;
    flex-grow: 1;
}

.sw-pricing-features li {
    position: relative;
    padding-left: 1.5rem;
    margin-bottom: 0.75rem;
    color: var(--sw-text);
    font-size: var(--sw-text-md);
}

.sw-pricing-features li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 0.875rem;
    height: 0.875rem;
    background: var(--sw-brand);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/contain no-repeat;
}

.sw-pricing-feature-note {
    display: block;
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-sm);
    margin-top: 0.125rem;
}

/* Billing-period toggle */
.sw-billing-toggle {
    display: inline-flex;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    padding: 4px;
    margin: 0 auto 2.5rem;
    gap: 4px;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}

.sw-billing-toggle-btn {
    background: transparent;
    border: none;
    padding: 0.5rem 1.25rem;
    border-radius: var(--sw-radius-btn);
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary);
    cursor: pointer;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: background 0.15s ease, color 0.15s ease;
}

.sw-billing-toggle-btn:hover {
    color: var(--sw-text);
}

.sw-billing-toggle-btn.sw-billing-toggle-active {
    background: var(--sw-bg);
    color: var(--sw-text);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.sw-pricing-billing-note {
    margin: -0.5rem 0 1.25rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

/* ── Legal pages ── */

.sw-imprint-hero {
    min-height: auto;
}

.sw-legal-section {
    max-width: 720px;
    margin: 0 auto;
}

.sw-legal-section h2 {
    font-size: var(--sw-text-2xl);
    font-weight: 600;
    color: var(--sw-text);
    margin: 2rem 0 0.75rem;
}

.sw-legal-section h2:first-child {
    margin-top: 0;
}

.sw-legal-block {
    color: var(--sw-text);
    line-height: 1.7;
    margin: 0 0 1rem;
}

.sw-pricing-cta {
    width: 100%;
    text-align: center;
}

.sw-pricing-cta:disabled,
.sw-pricing-cta[disabled] {
    background: var(--sw-disabled-bg);
    border-color: var(--sw-disabled-bg);
    color: var(--sw-disabled-text);
    cursor: not-allowed;
}

@media (max-width: 991.98px) {
    .sw-pricing-grid {
        grid-template-columns: 1fr;
    }
    .sw-pricing-card--featured {
        order: -1;
    }

}

/* ── Pricing UX refinements ── */

.sw-pricing-section-heading {
    text-align: center;
    margin-bottom: 1.5rem;
}

/* Lift + emphasize the featured (Pro) card on desktop. */
.sw-pricing-card--featured {
    position: relative;
    z-index: 1;
    transform: scale(1.04);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.10);
    border-color: var(--sw-brand-text);
}

.sw-pricing-card--featured:hover {
    transform: scale(1.04) translateY(-2px);
    box-shadow: var(--sw-shadow-lg);
}

/* Struck-through monthly price shown next to the yearly per-month amount. */
.sw-pricing-strike {
    text-decoration: line-through;
    color: var(--sw-text-muted);
    font-size: var(--sw-text-xl);
    font-weight: 500;
}

/* Subtle success pill near the price in yearly mode. */

/* "Everything in X, plus:" prefix above a card's feature list. */
.sw-pricing-includes {
    margin: 0 0 0.75rem;
}

/* Differentiator features: bolder text + a stronger check accent, no border. */
.sw-pricing-feature--highlight {
    font-weight: 600;
}

.sw-pricing-feature--highlight::before {
    background: var(--sw-brand);
    opacity: 1;
}

/* Trust row beneath the cards. */
.sw-pricing-trust {
    list-style: none;
    margin: 2rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.25rem 2rem;
}

.sw-pricing-trust-item {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

.sw-pricing-trust-item svg {
    flex-shrink: 0;
    color: var(--sw-success);
}

/* FAQ accordion. */
.sw-pricing-faq-section {
    padding-top: 0;
}

.sw-pricing-faq {
    max-width: 760px;
    margin: 0 auto;
}

/* The account FAQ (#823) and the pricing FAQ share one rule set: two names,
   one look, no second pattern. When the pricing page is redesigned it can drop
   its own class and use .sw-faq. */
.sw-pricing-faq-item,
.sw-faq__item {
    border-bottom: 1px solid var(--sw-border);
}

.sw-pricing-faq-item summary,
.sw-faq__item summary {
    list-style: none;
    cursor: pointer;
    padding: 1.125rem 2rem 1.125rem 0;
    min-height: 44px;
    position: relative;
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
    display: flex;
    align-items: center;
}

.sw-pricing-faq-item summary::-webkit-details-marker,
.sw-faq__item summary::-webkit-details-marker {
    display: none;
}

.sw-pricing-faq-item summary::after,
.sw-faq__item summary::after {
    content: "";
    position: absolute;
    right: 0.25rem;
    top: 50%;
    width: 0.75rem;
    height: 0.75rem;
    transform: translateY(-50%) rotate(0deg);
    background: var(--sw-text-secondary);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center/contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center/contain no-repeat;
    transition: transform 0.15s ease;
}

.sw-pricing-faq-item[open] summary::after,
.sw-faq__item[open] summary::after {
    transform: translateY(-50%) rotate(180deg);
}

.sw-pricing-faq-item summary:focus-visible,
.sw-faq__item summary:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
    border-radius: var(--sw-radius-sm);
}

.sw-pricing-faq-item p,
.sw-faq__item p {
    margin: 0 0 1.125rem;
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-md);
    line-height: 1.6;
}

/* Account FAQ wrapper: sits under the "what does this value measure?" section
   at the end of a metric page, so it brings its own top spacing (#823). */
.sw-faq {
    margin-top: var(--sw-space-5);
}
.sw-faq__list {
    border-top: 1px solid var(--sw-border);
}

/* Touch targets. */
.sw-billing-toggle-btn,
.sw-pricing-cta {
    min-height: 44px;
}

@media (prefers-reduced-motion: reduce) {
    .sw-pricing-card--featured,
    .sw-pricing-card--featured:hover {
        transform: none;
    }

}

@media (max-width: 991.98px) {
    .sw-pricing-card--featured,
    .sw-pricing-card--featured:hover {
        transform: none;
    }

}

@media (max-width: 575.98px) {
    .sw-billing-save-badge,
    .sw-pricing-saving {
        white-space: nowrap;
    }
    .sw-pricing-trust {
        flex-direction: column;
        align-items: center;
        gap: 0.75rem;
    }

}

/* Dark mode */
html.sw-dark .sw-pricing-card--featured {
    box-shadow: 0 12px 40px rgba(59, 130, 246, 0.2);
}
html.sw-dark .sw-pricing-faq-item p,
html.sw-dark .sw-faq__item p {
    color: var(--sw-text-secondary);
}

/* ── Locale Switcher ── */
.sw-locale-switcher {
    display: inline-flex;
    align-items: center;
    margin-left: 1rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
}
.sw-locale-link {
    color: var(--sw-text-secondary);
    text-decoration: none;
    padding: 0 0.25rem;
    transition: color 120ms ease;
}
.sw-locale-link:hover {
    color: var(--sw-text);
}
.sw-locale-link--active {
    color: var(--sw-brand-text);
    font-weight: 600;
}
.sw-locale-sep {
    color: var(--sw-text-muted);
    margin: 0 0.125rem;
}
@media (max-width: 767.98px) {
    .sw-locale-switcher {
        margin-left: 0.5rem;
        font-size: var(--sw-text-xs);
    }
    .sw-locale-link {
        padding: 0.5rem 0.25rem;
    }

}

/* ── Admin Shop Pager & Search ── */
.sw-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.25rem;
}
.sw-pager-status {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    text-align: center;
    flex: 1;
}
.sw-pager .sw-btn.disabled,
.sw-pager .sw-btn[aria-disabled="true"] {
    background: var(--sw-disabled-bg);
    border-color: var(--sw-disabled-bg);
    color: var(--sw-disabled-text);
    pointer-events: none;
    cursor: not-allowed;
}
.sw-list-search {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    max-width: 480px;
}
.sw-list-search .sw-form-control {
    flex: 1;
}
.sw-list-search-status {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin-bottom: 0.75rem;
}
.sw-list-search-status a {
    margin-left: 0.5rem;
    color: var(--sw-brand-text);
}
@media (max-width: 767.98px) {
    .sw-pager {
        flex-wrap: wrap;
    }
    .sw-pager-status {
        order: -1;
        flex-basis: 100%;
    }

}

/* ── Account dashboard: portfolio summary & section label ── */

/* Pending / not-yet-scored shop card meta */

/* ── Shops list: status pill & meta row ── */

.sw-shop-item-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    margin-bottom: 0;
}

.sw-shop-item-meta .sw-shop-date {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

.sw-shop-status {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
}

.sw-shop-status-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    background: currentColor;
}

.sw-shop-status--up {
    color: var(--sw-success);
}

.sw-shop-status--down {
    color: var(--sw-poor-text);
}

.sw-shop-status--pending {
    color: var(--sw-warning);
}

/* ── Analysis-in-progress badge ──
   Neutral (non-traffic-light) indicator shown per shop while a check run is in
   flight. Subtle background pill + pulsing dot; no brand-colored left border. */
.sw-analysis-badge { line-height: 1.4; white-space: nowrap; }

.sw-analysis-badge__pulse {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--sw-text-secondary);
    animation: sw-analysis-pulse 1.4s ease-in-out infinite;
}

@keyframes sw-analysis-pulse {
    0%, 100% {
        opacity: 0.35;
        transform: scale(0.85);
    }
    50% {
        opacity: 1;
        transform: scale(1);
    }
}

@media (prefers-reduced-motion: reduce) {
    .sw-analysis-badge__pulse {
        animation: none;
        opacity: 0.8;
    }

}

@media (max-width: 575.98px) {
    .sw-shop-item-content {
        flex-wrap: wrap;
    }

    .sw-shop-item-actions {
        flex-wrap: wrap;
        margin-left: 0;
        width: 100%;
    }

}

/* ── Multi-page monitoring ── */

/* Optional listing/detail fields in the add-shop form */

/* Per-page score breakdown on the dashboard shop card.
   Fixed order (Homepage · Listing · Detail), always three slots, always on a
   single row - the shop-card grid below widens the cards enough to hold them. */

/* Quiet "Add" affordance for a missing page slot. Deliberately subdued
   (dashed, muted) so real score pills keep the attention; brand-tinted only
   on hover to signal it's actionable. */

/* ── Ranking (redesign) ── */

/* Compact hero: the shared .sw-hero-wrapper is a full-height flex column whose
   .container / .sw-hero children stretch with flex:1 and carry 4rem padding.
   On the ranking page we only want it as tall as its content, so we collapse
   both the wrapper height and the inherited flex-stretch + padding. */

/* Hero trust stats: 2-3 large numbers instead of one muted line. */

/* Movers strip */

/* Falling movers use amber (a neutral "declining" signal), not brand red -
   the down-arrow icon still conveys direction, and brand red stays reserved
   for branding / your-own-shops / CTAs / the active tab. */

/* Tinted backgrounds so "green rises / amber falls" is scannable at a glance.
   color-mix against --sw-bg auto-darkens in dark mode. */

/* Find-my-shop bar */

/* Category tabs */

/* Tab busy spinner - revealed only while the frame is loading. */
/* Speed-tab hint: lower response time is better. */

/* Your-shops strip: a brand-accented panel (not a second grey movers box) so
   "your shops" reads as personal at a glance. Brand-tinted bg + left border. */

/* Your-shops chip: clearer link affordance. */

/* Podium */

/* #1 - the tallest step: bigger gold border, a gold top-glow on top of the
   existing drop shadow, and a thin gold accent bar across the top edge. */

/* #2 / #3 are genuinely shorter steps, not just narrower: less top padding
   pulls their content down so the podium reads as a staircase. */

/* Larger, brighter medal on #1. */

/* Position cluster + delta pill */

/* Down delta: amber, not brand red - direction is carried by the ▼ glyph and
   the aria-label, so red stays reserved for branding / CTAs. */

/* Meta row under the domain: gap pill (emphasised) + timestamp (muted). */

/* "+N to overtake" - the most motivating data point, raised to a pill. */

/* Timestamp is intentionally quieter than the gap pill. */

/* Per-row badges */

/* Flat rows (rank 11+): dense, divider-separated lines instead of individual
   raised cards - calmer when the board runs to ~97 entries. Ranks 4-10 keep
   the card look as a transition down from the podium. */

/* Search-match highlight pulse */

@media (prefers-reduced-motion: no-preference) {

    @keyframes sw-ranking-pulse {
        0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.35); }
        100% { box-shadow: 0 0 0 12px rgba(59, 130, 246, 0); }
    }

}

/* ── Billing hub & checkout (plan upgrade) ── */

/* Usage meter */

/* Interval toggle reuses .sw-billing-toggle from pricing; add top spacing here */
.sw-billing .sw-billing-toggle {
    margin: 0 auto 1.75rem;
}

/* Comparison grid */
.sw-billing-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
    margin-bottom: 1.5rem;
}
.sw-billing-card {
    position: relative;
    display: flex;
    flex-direction: column;
}
.sw-billing-card--featured {
    border-color: var(--sw-brand-text);
    box-shadow: 0 4px 24px rgba(59, 130, 246, 0.12);
}
.sw-billing-card-current {
    position: absolute;
    top: 1rem;
    right: 1rem;
}
.sw-billing-card-tier {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    margin-bottom: 0.5rem;
}
.sw-billing-price {
    display: flex;
    align-items: baseline;
    gap: 0.375rem;
    margin-bottom: 1rem;
}
.sw-billing-amount {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
}
.sw-billing-period {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}
.sw-billing-features {
    flex: 1 1 auto;
    margin-bottom: 1.25rem;
}
.sw-billing-card-cta .sw-btn {
    width: 100%;
}
.sw-billing-card-cta form {
    margin: 0;
}

/* Net-VAT note */
.sw-billing-net-note {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin-top: 0.5rem;
}
.sw-billing-net-note svg {
    flex: 0 0 auto;
    color: var(--sw-text-secondary);
}

/* Blocked pricing CTA (logged-in member / current plan) */
.sw-pricing-cta-blocked {
    cursor: default;
    opacity: 0.7;
}

/* Return landing */
.sw-billing-return {
    max-width: 520px;
    margin: 1rem auto;
}
.sw-billing-return .sw-card {
    text-align: center;
}
.sw-billing-return h1 {
    font-size: var(--sw-text-3xl);
    margin: 1rem 0 0.5rem;
}
.sw-billing-return p {
    color: var(--sw-text-secondary);
    margin-bottom: 1.25rem;
}
.sw-billing-pending,
.sw-billing-success {
    border-radius: var(--sw-radius-card);
}

/* The honest long-wait card: same frame as the pending one, but no spinner. A
   turning circle promises movement we cannot promise (founder review 2026-09-04). */
.sw-billing-pending--long .sw-billing-pending__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    margin: 0 auto 1rem;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
}

.sw-billing-pending--long .sw-billing-pending__note {
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-md);
    margin-bottom: 1.25rem;
}
.sw-billing-poll-notice {
    margin-top: 1rem;
    text-align: left;
}

/* Payment success animation (FE-52) - plays on the active card and the pending→active flip.
   CSS default is the FINAL success state so JS-off / reduced-motion still reads right;
   only transform/opacity are animated (GPU), so it stays smooth. */
.sw-pay-host {
    position: relative;
    overflow: hidden;
}
.sw-pay-confetti {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 3;
}
.sw-pay-icon {
    position: relative;
    width: 88px;
    height: 88px;
    margin: 0.25rem auto 0;
    display: grid;
    place-items: center;
}
.sw-pay-glow {
    position: absolute;
    width: 150px;
    height: 150px;
    border-radius: var(--sw-radius-btn);
    filter: blur(26px);
    background: radial-gradient(closest-side, var(--sw-success), transparent);
    opacity: 0.28;
    pointer-events: none;
    will-change: opacity, transform;
}
.sw-pay-disc {
    position: relative;
    width: 88px;
    height: 88px;
    border-radius: var(--sw-radius-btn);
    display: grid;
    place-items: center;
    background: linear-gradient(150deg, var(--sw-success), var(--sw-success-dark));
    transition: background 0.45s ease;
    will-change: transform;
}
.sw-pay-disc--pending {
    background: linear-gradient(150deg, var(--sw-brand), var(--sw-brand-strong));
}
.sw-pay-check {
    width: 46px;
    height: 46px;
    color: #fff;
    will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
    .sw-pay-glow,
    .sw-pay-disc {
        transition: none;
    }

}

/* CSS-only spinner */
.sw-spinner {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: var(--sw-radius-btn);
    animation: sw-spin 0.7s linear infinite;
}
.sw-spinner--lg {
    width: 2rem;
    height: 2rem;
    border-width: 3px;
    color: var(--sw-brand-text);
}
@keyframes sw-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Dark mode */
html.sw-dark .sw-billing-period,
html.sw-dark .sw-billing-net-note,
html.sw-dark .sw-billing-net-note svg,
html.sw-dark .sw-billing-return p {
    color: var(--sw-text-secondary);
}
html.sw-dark .sw-billing-amount {
    color: var(--sw-text);
}
html.sw-dark .sw-billing-card--featured {
    box-shadow: 0 4px 24px rgba(59, 130, 246, 0.2);
}

/* Responsive */
@media (max-width: 991.98px) {
    .sw-billing-grid {
        grid-template-columns: 1fr;
    }
    .sw-billing-grid .sw-billing-card--featured {
        order: -1;
    }

}

/* ── History tabs (metric detail: Chart ⇄ Table) ── */

.sw-history-tabs {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.25rem;
    background: var(--sw-bg-subtle);
    border-radius: var(--sw-radius-btn);
}

.sw-history-tab {
    padding: 0.375rem 0.875rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-secondary);
    background: none;
    border: none;
    border-radius: var(--sw-radius-btn);
    cursor: pointer;
    transition: color 0.15s, background 0.15s, box-shadow 0.15s;
}

.sw-history-tab:hover {
    color: var(--sw-text);
}

.sw-history-tab.sw-tab-active {
    color: var(--sw-text);
    background: var(--sw-bg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

html.sw-dark .sw-history-tab.sw-tab-active {
    box-shadow: var(--sw-shadow-sm);
}

/* ── Benchmark bar (metric detail) ── */

.sw-benchmark-head {
    margin-bottom: 1.25rem;
}

.sw-benchmark-title {
    font-size: var(--sw-text-2xl);
    font-weight: 600;
    margin: 0 0 0.25rem;
}

.sw-benchmark-sub {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0;
}

.sw-benchmark {
    position: relative;
}

/* Rails reserve vertical room for the marker flags above and below the track. */
.sw-benchmark-rail {
    position: relative;
    height: 2.75rem;
}

.sw-benchmark-rail--top {
    margin-bottom: 0.5rem;
}

.sw-benchmark-rail--bottom {
    margin-top: 0.5rem;
}

.sw-benchmark-track {
    position: relative;
    display: flex;
    height: 14px;
    border-radius: var(--sw-radius-control);
    overflow: visible;
    border: 1px solid var(--sw-border);
}

.sw-benchmark-zone {
    height: 100%;
    opacity: 0.88;
}

/* Neutral full-width track for metrics without rating thresholds (e.g. request
   count): no good/bad colour, just a backdrop for the two comparison markers. */
.sw-benchmark-zone--neutral {
    background: var(--sw-border);
    opacity: 1;
    border-radius: var(--sw-radius-sm);
}

.sw-benchmark-zone:first-child {
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
}

.sw-benchmark-zone:last-child {
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
}

/* Vertical marker lines sitting on top of the zones. */
.sw-benchmark-marker {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 3px;
    transform: translateX(-50%);
    border-radius: 2px;
    box-shadow: 0 0 0 2px var(--sw-bg);
}

.sw-benchmark-marker--own {
    background: var(--sw-text);
}

.sw-benchmark-marker--median {
    background: repeating-linear-gradient(
        var(--sw-text-secondary),
        var(--sw-text-secondary) 3px,
        transparent 3px,
        transparent 6px
    );
    box-shadow: none;
}

/* Competitor markers: small numbered brand-coloured pins on the track. The number
   (matched in the legend below) carries identity so they're distinguishable beyond
   colour alone, and stay readable however many competitors there are. */
.sw-benchmark-marker--competitor {
    top: -7px;
    bottom: -7px;
    width: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--sw-brand-strong); /* #648 */
    border-radius: var(--sw-radius-control);
    box-shadow: 0 0 0 2px var(--sw-bg);
    color: #fff;
    font-size: var(--sw-text-2xs);
    font-weight: 700;
    line-height: 1;
    z-index: 1;
}

/* Floating labels that point at their marker. */
.sw-benchmark-flag {
    position: absolute;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    white-space: nowrap;
    line-height: 1.2;
    pointer-events: none;
}

.sw-benchmark-rail--top .sw-benchmark-flag {
    bottom: 0;
}

.sw-benchmark-rail--bottom .sw-benchmark-flag {
    top: 0;
}

.sw-benchmark-flag-label {
    font-size: var(--sw-text-xs);
    font-weight: 500;
    color: var(--sw-text-secondary);
}

.sw-benchmark-flag-value {
    font-size: var(--sw-text-sm);
    font-weight: 700;
    color: var(--sw-text);
}

/* Caret connecting the flag to its marker. */
.sw-benchmark-flag::after {
    content: '';
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
}

.sw-benchmark-rail--top .sw-benchmark-flag--own::after {
    border-top: 5px solid var(--sw-text);
    margin-top: 3px;
}

.sw-benchmark-rail--bottom .sw-benchmark-flag--median::after {
    order: -1;
    border-bottom: 5px solid var(--sw-text-secondary);
    margin-bottom: 3px;
}

/* Edge-aligned flags: at the far right/left the label is anchored to the marker
   side instead of centred, so it never clips past the bar's edge. */
.sw-benchmark-flag.is-right {
    transform: translateX(-100%);
    align-items: flex-end;
}

.sw-benchmark-flag.is-left {
    transform: translateX(0);
    align-items: flex-start;
}

/* Keep the caret over the marker line when the flag is edge-anchored. */
.sw-benchmark-flag.is-right::after {
    align-self: flex-end;
}

.sw-benchmark-flag.is-left::after {
    align-self: flex-start;
}

.sw-benchmark-scale {
    display: flex;
    justify-content: space-between;
    margin-top: 0.5rem;
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
}

.sw-benchmark-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    margin-top: 1.25rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-benchmark-legend span {
    display: inline-flex;
    align-items: center;
}

/* Competitor key: maps each numbered track dot to a competitor name + value. */
.sw-benchmark-competitors {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--sw-border);
}

.sw-benchmark-competitors-title {
    display: block;
    margin-bottom: 0.625rem;
}

.sw-benchmark-competitors-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
}

.sw-benchmark-competitor {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-benchmark-competitor-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: var(--sw-radius-control);
    background: var(--sw-brand-strong); /* #648 */
    color: #fff;
    font-size: var(--sw-text-2xs);
    font-weight: 700;
    line-height: 1;
}

.sw-benchmark-competitor-name {
    font-weight: 500;
    color: var(--sw-text);
}

.sw-benchmark-competitor-value {
    font-weight: 700;
    color: var(--sw-text);
}

@media (max-width: 767.98px) {
    .sw-benchmark-flag-label {
        font-size: var(--sw-text-2xs);
    }

    .sw-benchmark-flag-value {
        font-size: var(--sw-text-xs);
    }

}

/* ── "How to reach 100" Pro teaser ── */
.sw-badge-pro {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-dark);
    border-color: #BFDBFE;
}

html.sw-dark .sw-badge-pro {
    background: rgba(59, 130, 246, 0.1);
    border-color: rgba(59, 130, 246, 0.25);
    color: var(--sw-brand-light);
}

/* Free reveal on metric pages (#354): revealed actions of this category */
.sw-free-actions { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.sw-free-actions__item { display: flex; align-items: flex-start; gap: .625rem; font-size: var(--sw-text-md); color: var(--sw-text); }
/* #955 A-10: the icon is an opened lock in brand tint - the finding is unlocked, not passed. */
.sw-free-actions__check { flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--sw-brand-tint); color: var(--sw-brand-text); margin-top: .1rem; }
.sw-free-actions__check svg { width: 13px; height: 13px; }
.sw-free-actions__body { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.sw-free-actions__body .sw-nba__advice { margin: 0; }
.sw-free-actions__text { flex: 1; }
.sw-free-actions__form { margin: 0 0 1rem; }
/* #506: marks the Free reveal list as self-unlocked so a Free viewer sees why
   only some recommendations show. Dezent, success-toned, open-padlock icon. */
.sw-free-actions__unlocked {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    margin: 0 0 .625rem;
    font-size: var(--sw-text-xs);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--sw-success);
}
.sw-free-actions__unlocked svg { width: 14px; height: 14px; }

/* ── Team / Workspace management (Phase 4) ── */

.sw-team-avatar {
    border-radius: 50%;
    flex-shrink: 0;
}

.sw-team-role-form {
    margin: 0;
}

.sw-team-role-select {
    width: auto;
    min-width: 7rem;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}

.sw-team-no-action {
    /* #920 (F-13): inherited the 1rem body size, a step above the rest of the row. */
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

.sw-team-accept-intro {
    text-align: center;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin-bottom: 1.5rem;
}

/* ── Competitors ── */
.sw-table-wrapper {
    overflow-x: auto;
}

.sw-competitor-table th[scope="col"] {
    vertical-align: top;
    white-space: nowrap;
}

.sw-competitor-table .sw-competitor-col-own {
    background: var(--sw-bg-subtle);
}

.sw-competitor-col-name {
    display: inline-block;
    margin-right: 0.375rem;
    font-weight: 600;
}

.sw-competitor-value {
    font-weight: 600;
    color: var(--sw-text);
}

.sw-competitor-na {
    color: var(--sw-text-muted);
    font-style: italic;
}

.sw-competitor-analyzing {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-base);
}

/* Better/worse markers carry a text label + glyph (not colour alone) for AA access. */
.sw-competitor-marker {
    display: inline-block;
    margin-left: 0.5rem;
    font-size: var(--sw-text-xs);
    font-weight: 600;
    white-space: nowrap;
}

/* Competitor ahead of your shop = bad for you → brand (red, AA on white). */
.sw-competitor-marker--ahead {
    /* #667 (INS-27): "ahead of you" is a warning, not a brand accent. */
    color: var(--sw-warning-text);
}
html.sw-dark .sw-competitor-marker--ahead {
    color: var(--sw-warning);
}

/* Competitor behind your shop = good for you → success (AA-dark variant). */
.sw-competitor-marker--behind {
    color: var(--sw-success-dark);
}

.sw-competitor-marker--equal {
    color: var(--sw-text-muted);
}

@media (max-width: 767.98px) {
    .sw-competitor-marker {
        display: block;
        margin-left: 0;
    }

}

/* ── Competitor comparison charts (small multiples) ── */
.sw-competitor-chart {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
}

.sw-competitor-hero {
    margin-bottom: var(--sw-space-4);
}

.sw-competitor-grid {
    margin-bottom: var(--sw-space-4);
}

/* Bar charts grow downward with the number of competitors; the inline height
   var (set per chart) keeps every bar legible instead of squeezing them. */

.sw-competitor-legend {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-secondary);
    margin: 0.75rem 0 0;
}

/* ── Horizontal benchmark bars (replaces the per-metric Chart.js canvas) ── */
.sw-competitor-bars {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.sw-competitor-bar-row {
    display: grid;
    grid-template-columns: minmax(96px, 168px) 1fr auto;
    align-items: center;
    gap: 0.85rem;
    padding: 0.3rem 0.45rem;
    border-radius: var(--sw-radius-control);
}

.sw-competitor-bar-row.is-own {
    background: var(--sw-brand-tint);
}

.sw-competitor-bar-name {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sw-competitor-bar-row.is-own .sw-competitor-bar-name {
    color: var(--sw-text);
    font-weight: 600;
}

.sw-competitor-bar-track {
    height: 10px;
    background: var(--sw-bg-subtle);
    border-radius: var(--sw-radius-btn);
    overflow: hidden;
}

/* No width transition on purpose - the comparison fragment is re-rendered every
   few seconds by the poll while a competitor is still analysing; an entry
   animation would make every bar flicker on each tick. */
.sw-competitor-bar-fill {
    display: block;
    height: 100%;
    border-radius: var(--sw-radius-btn);
}

.sw-competitor-bar-value {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.4rem;
    font-size: var(--sw-text-sm);
    white-space: nowrap;
}

/* The notify offer used to be squeezed onto the value line and read as a stray
   word. It gets its own row and real button weight instead. */
.sw-competitor-notify-wrap { flex-basis: 100%; display: flex; justify-content: flex-end; flex-wrap: wrap; }
.sw-competitor-notify-btn { white-space: nowrap; }
.sw-competitor-notify-btn svg { width: 15px; height: 15px; margin-right: .4rem; }

/* "How to read this" explainer above the bars. */
.sw-competitor-explainer {
    font-size: var(--sw-text-sm);
    line-height: 1.6;
    color: var(--sw-text-secondary);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-inline);
    padding: 0.75rem 1rem;
    margin: 0 0 var(--sw-space-4);
}

.sw-competitor-explainer strong { color: var(--sw-text); }
.sw-competitor-explainer .sw-light { margin: 0 0.15rem 0 0.35rem; }
.sw-competitor-explainer .sw-competitor-marker { margin: 0 0.1rem; }

/* ── Compact "add a competitor" form (Option B, #537: lives in the secondary
   "manage competitors" section, below the comparison once one exists) ── */
.sw-competitor-add {
    margin-bottom: var(--sw-space-5);
}

.sw-competitor-add-head {
    margin-bottom: var(--sw-space-3);
}

.sw-competitor-add-title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--sw-text);
    margin: 0 0 0.25rem;
}

.sw-competitor-add-hint {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    line-height: 1.5;
    margin: 0;
    max-width: 64ch;
}

@media (max-width: 600px) {
    .sw-competitor-bar-row {
        grid-template-columns: 1fr auto;
        row-gap: 0.4rem;
    }
    .sw-competitor-bar-track {
        grid-column: 1 / -1;
        order: 3;
    }

}

.sw-competitor-no-own {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-md, 8px);
    padding: 0.625rem 0.875rem;
    margin-bottom: var(--sw-space-4);
}

/* Disclosure wrapping the full data table (A11y + power-user exact values). */
.sw-competitor-details {
    margin-top: var(--sw-space-4);
}

.sw-competitor-details-toggle {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 0.25rem;
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary);
    list-style: none;
}

.sw-competitor-details-toggle::-webkit-details-marker {
    display: none;
}

.sw-competitor-details-toggle::before {
    content: '▸';
    margin-right: 0.5rem;
    transition: transform 0.15s ease;
}

.sw-competitor-details[open] .sw-competitor-details-toggle::before {
    transform: rotate(90deg);
}

.sw-competitor-details-toggle:hover {
    color: var(--sw-text);
}

/* ── Competitor results lock block (Free plan gate) ── */

/* Dark mode */

/* ── Account context scope (Workspace ▸ Shop) ── */
/* Agency sidebars render the active workspace as a compact scope header above
   the (visually primary) shop selector, so the two read as one hierarchy
   "within [workspace] you work on [shop]" instead of two equal dropdowns.
   Free/Pro (one workspace) never render .sw-context-scope. */
.sw-context-scope {
    margin-bottom: 1rem;
}

/* The workspace selector inside the scope is the secondary (framing) control. */
.sw-context-scope .sw-workspace-selector {
    margin-bottom: 0;
}

.sw-context-scope .sw-shop-selector-toggle {
    background: var(--sw-bg-subtle);
}

/* Footnote inside the open workspace menu explaining the reload semantics. */
.sw-context-scope-hint {
    margin: 0.25rem 0.25rem 0.125rem;
    padding: 0.375rem 0.5rem 0;
    border-top: 1px solid var(--sw-border);
    font-size: var(--sw-text-2xs);
    line-height: 1.4;
    color: var(--sw-text-muted);
}

/* Empty-workspace hint shown when the active workspace has no shops yet. */
.sw-context-scope-empty {
    display: block;
    margin-top: 0.5rem;
    padding: 0 0.75rem;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-brand-text);
    text-decoration: none;
}

.sw-context-scope-empty:hover {
    color: var(--sw-brand-dark);
    text-decoration: underline;
}

/* The shop selector is indented and visually subordinate to its workspace. */
.sw-shop-selector--scoped {
    margin-left: 4px;
    margin-top: var(--sw-space-2);
}

/* Touch targets: keep toggle and options >= 44px on the scoped selectors. */
.sw-context-scope .sw-shop-selector-toggle,
.sw-shop-selector--scoped .sw-shop-selector-toggle,
.sw-context-scope .sw-shop-selector-option,
.sw-shop-selector--scoped .sw-shop-selector-option {
    min-height: 44px;
}

html.sw-dark .sw-context-scope .sw-shop-selector-toggle {
    background: var(--sw-dark-bg-subtle);
    border-color: var(--sw-dark-border);
}

html.sw-dark .sw-context-scope-hint {
    border-top-color: var(--sw-dark-border);
    color: var(--sw-dark-text-secondary);
}

/* ── Add-shop disclosure (native <details>) ── */
/* Progressive disclosure for the optional listing/detail URLs: keeps the
   single domain field + one primary action in focus, reveals extras on demand.
   Native <details>/<summary> - keyboard + screenreader support for free. */

/* Micro-explanation row in the add-shop card (icon + reassurance copy). */
.sw-shop-add-check {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}

.sw-shop-add-check svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--sw-text-muted);
}

/* ── Workspace members (card/row list) ── */
/* Styles moved to the Teams block at the end of this file (FE-23). */

@media (max-width: 767.98px) {
    /* Context scope + shop selector stay a vertical, full-width block on mobile. */
    .sw-shop-selector--scoped {
        margin-left: 0;
    }

    /* Invite card: email/role/button stack, button full-width. */

}

/* ════════════════════════════════════════════════════════════
   Dashboard redesign - score bar, KPI hero, modern shop cards,
   widgets, slim app footer, sidebar groups. Token-driven, dark-safe.
   ════════════════════════════════════════════════════════════ */

/* ── Slim app footer (Prio 1) ── */

.sw-app-footer {
    border-top: 1px solid var(--sw-border);
    background: var(--sw-bg);
    margin-top: var(--sw-space-8);
    padding: var(--sw-space-4) 0;
}

.sw-app-footer-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sw-space-4);
    flex-wrap: wrap;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-app-footer-copy {
    color: var(--sw-text-secondary);
}

.sw-app-footer-links {
    display: flex;
    align-items: center;
    gap: var(--sw-space-2);
}

.sw-app-footer-links a {
    color: var(--sw-text-secondary);
    text-decoration: none;
    transition: color 0.15s;
}

.sw-app-footer-links a:hover {
    color: var(--sw-text);
}

.sw-app-footer-sep {
    color: var(--sw-text-muted);
}

@media (max-width: 575.98px) {
    .sw-app-footer-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--sw-space-3);
    }

}

/* ── Score bar (Prio 2/3 shared component) ── */

.sw-score-bar {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-2);
}

.sw-score-bar__track {
    height: 8px;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-bg-subtle);
    overflow: hidden;
}

.sw-score-bar__fill {
    height: 100%;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-text-muted);
    transition: width 0.6s ease;
}

.sw-score-bar--good .sw-score-bar__fill { background: var(--sw-success); }
.sw-score-bar--moderate .sw-score-bar__fill { background: var(--sw-warning); }
.sw-score-bar--poor .sw-score-bar__fill { background: var(--sw-danger); }

/* Empty / analyzing state - skeleton shimmer on the track. */
.sw-score-bar--empty .sw-score-bar__track {
    background: linear-gradient(90deg, var(--sw-bg-subtle) 25%, var(--sw-border) 50%, var(--sw-bg-subtle) 75%);
    background-size: 200% 100%;
    animation: sw-score-shimmer 1.4s ease-in-out infinite;
}

@keyframes sw-score-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .sw-score-bar--empty .sw-score-bar__track { animation: none; }
    .sw-score-bar__fill { transition: none; }

}

/* ── Trend pill (Prio 2) - reuses the ranking-delta look ── */

/* ── KPI tiles (Prio 2) ── */

/* Stat tiles live in the admin only (founder decision on Q12, 2026-09-09,
   #849): it is an internal surface. In the product a figure belongs in a quiet
   line - see .sw-figures. */
.sw-stat-tile {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-2);
    padding: var(--sw-space-5);
    align-items: flex-start;
}

.sw-stat-tile:hover {
    transform: none;
    box-shadow: var(--sw-shadow-sm);
}

.sw-stat-tile-value {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    color: var(--sw-text);
}

.sw-stat-tile-label {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

/* Success state - "All shops healthy" (Prio 2/4) */

/* ── Modern shop cards (Prio 3) ── */

/* ── Dashboard widgets (Prio 4) ── */

/* Single-widget row (portfolio trend only - the "needs attention" message lives
   in the KPI card, so the widgets row no longer pairs a duplicate block). */

.sw-widget {
    border-radius: var(--sw-radius-lg);
    box-shadow: var(--sw-shadow-sm);
    padding: var(--sw-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-4);
}

.sw-widget__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sw-space-3);
}

.sw-widget__title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
}

.sw-widget__sub {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-trend-toggle {
    display: inline-flex;
    gap: 0.125rem;
    padding: 0.1875rem;
    background: var(--sw-bg-subtle);
    border-radius: var(--sw-radius-btn);
}

.sw-trend-toggle-btn {
    font-size: var(--sw-text-xs);
    font-weight: 600;
    padding: 0.25rem 0.625rem;
    border: none;
    background: none;
    border-radius: var(--sw-radius-btn);
    color: var(--sw-text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.sw-trend-toggle-btn.sw-billing-toggle-active {
    background: var(--sw-bg);
    color: var(--sw-text);
    box-shadow: var(--sw-shadow-sm);
}

/* ── Section titles (Prio 6 hierarchy) ── */

.sw-section-title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
    margin: var(--sw-space-6) 0 var(--sw-space-3);
}

/* ── Sidebar group (Prio 5) ── */

.sw-sidebar-group {
    margin-top: var(--sw-space-4);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sw-sidebar-group:first-of-type {
    margin-top: var(--sw-space-1);
}

/* ── Score explainer (disclosure under the headline score) ── */

.sw-score-explainer {
    margin-top: var(--sw-space-3);
}

.sw-score-explainer-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--sw-space-1);
    cursor: pointer;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    /* Trust-building link (explains how the headline score is computed) - styled as a
       normal link rather than muted grey so it reads as inviting, not decorative. */
    color: var(--sw-brand-text);
    list-style: none;
}

.sw-score-explainer-toggle::-webkit-details-marker {
    display: none;
}

.sw-score-explainer-toggle svg {
    width: 15px;
    height: 15px;
}

.sw-score-explainer-toggle:hover {
    text-decoration: underline;
}

.sw-score-explainer-body {
    margin: var(--sw-space-2) 0 0;
    font-size: var(--sw-text-sm);
    line-height: 1.6;
    color: var(--sw-text-secondary);
    max-width: 38ch;
}

/* ── Sub-score cards (Analytics overview) ── */

.sw-subscore-card {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-2);
    height: 100%;
    padding: 1.25rem;
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    text-decoration: none;
    transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

.sw-subscore-card:hover {
    box-shadow: var(--sw-shadow-md);
    transform: translateY(-2px);
    border-color: var(--sw-border);
}

.sw-subscore-card:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
    border-color: var(--sw-brand-text);
}

.sw-subscore-head {
    display: flex;
    align-items: center;
    gap: var(--sw-space-2);
}

.sw-subscore-card .sw-card-icon {
    width: 40px;
    height: 40px;
    margin-bottom: 0;
    flex-shrink: 0;
}

.sw-subscore-card .sw-card-icon svg {
    width: 20px;
    height: 20px;
}

.sw-subscore-title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0;
}

.sw-subscore-score {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.sw-subscore-number {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--sw-text);
}

.sw-subscore-unit {
    font-size: var(--sw-text-base);
    color: var(--sw-text-muted);
}

.sw-subscore-rating {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-text-secondary);
}

.sw-subscore-card.sw-score-bar--good .sw-subscore-rating { color: var(--sw-success-text); }
.sw-subscore-card.sw-score-bar--moderate .sw-subscore-rating { color: var(--sw-warning-text); }
.sw-subscore-card.sw-score-bar--poor .sw-subscore-rating { color: var(--sw-poor-text); }
.sw-subscore-card.sw-score-bar--empty .sw-subscore-number { color: var(--sw-text-muted); }

.sw-subscore-desc {
    font-size: var(--sw-text-sm);
    line-height: 1.5;
    color: var(--sw-text-secondary);
    margin: 0;
    flex-grow: 1;
}

.sw-subscore-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sw-space-2);
    margin-top: auto;
}

.sw-subscore-counts {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-muted);
}

.sw-subscore-view {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-brand-text);
    white-space: nowrap;
}

.sw-subscore-view--cta {
    color: var(--sw-brand-text);
}

/* ── Multi-Page Monitoring CTA (analytics #pages section) ──
   Permanent bento card inside sw-cmd-top, shown while at least one page type
   (Homepage/Listing/Detail) is still untracked. Spans the full row width. */

/* ── Profile Page ── */

/* ── Error Pages (403, 404) ── */
.sw-error-page { min-height: calc(100vh - var(--sw-navbar-height)); display:flex; align-items:center; justify-content:center; padding: var(--sw-space-8) var(--sw-space-5); }
.sw-error-content { max-width:480px; width:100%; text-align:center; display:flex; flex-direction:column; align-items:center; gap:var(--sw-space-4); }
.sw-error-icon-box { width:72px; height:72px; border-radius:var(--sw-radius-panel); background:var(--sw-poor-tint); display:flex; align-items:center; justify-content:center; color:var(--sw-danger); margin-bottom:var(--sw-space-2); }
.sw-error-code { font-size:3rem; /* #654: display cap */ font-weight:700; letter-spacing:-0.04em; line-height:1; color:var(--sw-text-muted); }
.sw-error-title { font-size:var(--sw-text-4xl); font-weight:700; letter-spacing:-0.02em; color:var(--sw-text); margin:0; text-wrap:balance; }
.sw-error-desc { font-size:var(--sw-text-lg); color:var(--sw-text-secondary); max-width:40ch; margin:0; line-height:1.6; }
.sw-error-actions { display:flex; flex-direction:column; align-items:center; gap:var(--sw-space-3); margin-top:var(--sw-space-2); }

/* ── Plan Upsell ── */
.sw-upsell-page {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: var(--sw-space-4) var(--sw-space-4) var(--sw-space-10);
}
.sw-upsell-inner {
    max-width: 580px;
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sw-space-8);
    text-align: center;
}

/* Plan progression (current → target) */
.sw-upsell-plan-progression {
    display: flex;
    align-items: center;
    gap: var(--sw-space-4);
    opacity: 1;
    transform: translateY(0);
    transition: opacity 200ms cubic-bezier(0.23, 1, 0.32, 1),
                transform 200ms cubic-bezier(0.23, 1, 0.32, 1);
}
@starting-style {
    .sw-upsell-plan-progression {
        opacity: 0;
        transform: translateY(6px);
    }
}
.sw-upsell-plan-badge {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    padding: var(--sw-space-1) var(--sw-space-3);
    border-radius: var(--sw-radius-btn);
    border: 1px solid var(--sw-border);
    background: var(--sw-bg-subtle);
    color: var(--sw-text-secondary);
}
.sw-upsell-plan-badge--target {
    background: var(--sw-brand-strong); /* #648 */
    border-color: var(--sw-brand-text);
    color: #fff;
}
.sw-upsell-progression-arrow {
    color: var(--sw-text-muted);
    display: flex;
    align-items: center;
}

/* Headline + subline */
.sw-upsell-headline {
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--sw-text);
    margin: 0;
    text-wrap: balance;
    line-height: 1.25;
}
.sw-upsell-sub {
    font-size: var(--sw-text-lg);
    color: var(--sw-text-secondary);
    margin: 0;
    max-width: 44ch;
    line-height: 1.6;
}

/* Feature list */
.sw-upsell-features {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-3);
    text-align: left;
}
.sw-upsell-feature {
    display: flex;
    align-items: flex-start;
    gap: var(--sw-space-3);
    padding: var(--sw-space-4);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-inline);
    opacity: 1;
    transform: translateY(0);
    transition: opacity 180ms cubic-bezier(0.23, 1, 0.32, 1),
                transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
}
@starting-style {
    .sw-upsell-feature {
        opacity: 0;
        transform: translateY(6px);
    }
}
.sw-upsell-feature:nth-child(1) { transition-delay: 60ms; }
.sw-upsell-feature:nth-child(2) { transition-delay: 100ms; }
.sw-upsell-feature:nth-child(3) { transition-delay: 140ms; }
.sw-upsell-feature:nth-child(4) { transition-delay: 180ms; }
.sw-upsell-feature:nth-child(5) { transition-delay: 220ms; }

.sw-upsell-feature-icon {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: var(--sw-radius-control);
    background: var(--sw-brand-tint);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--sw-brand-text);
    margin-top: 1px;
}
.sw-upsell-feature-title {
    font-size: var(--sw-text-md);
    font-weight: 600;
    color: var(--sw-text);
    display: block;
    margin-bottom: var(--sw-space-1);
}
.sw-upsell-feature-desc {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
    line-height: 1.5;
}

/* Actions */
.sw-upsell-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sw-space-3);
    width: 100%;
    opacity: 1;
    transition: opacity 160ms cubic-bezier(0.23, 1, 0.32, 1);
    transition-delay: 280ms;
}
@starting-style {
    .sw-upsell-actions {
        opacity: 0;
    }
}
.sw-upsell-compare-link {
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-secondary);
    text-decoration: none;
    transition: color 0.15s;
}
.sw-upsell-compare-link:hover { color: var(--sw-text); }
.sw-upsell-price {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin: 0;
}
.sw-upsell-back-link {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    text-decoration: none;
    transition: color 0.15s;
}
.sw-upsell-back-link:hover { color: var(--sw-text-secondary); }

/* Dark-mode adjustments */
.sw-dark .sw-upsell-feature { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.08); }
.sw-dark .sw-upsell-plan-badge { background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.1); color: var(--sw-text-muted); }
.sw-dark .sw-upsell-feature-icon { background: rgba(59, 130, 246, 0.15); }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .sw-upsell-plan-progression,
    .sw-upsell-feature,
    .sw-upsell-actions {
        transition: opacity 150ms ease;
        transform: none;
        transition-delay: 0ms;
    }

}

@media (max-width: 767.98px) {
    .sw-upsell-page { padding: var(--sw-space-8) var(--sw-space-4); align-items: flex-start; }
    .sw-upsell-headline { font-size: var(--sw-text-3xl); }
    .sw-upsell-actions .sw-btn { width: 100%; text-align: center; }

}
@media (max-width: 575.98px) { .sw-error-code { font-size:3rem; } .sw-error-title { font-size:var(--sw-text-3xl); } .sw-error-actions .sw-btn-primary-lg { width:100%; } 
}

/* ── Dashboard redesign: at-a-glance overview strip + entrance motion ── */

/*
    Two dashboard entrance animations, both gated behind no-preference so the
    page renders fully visible under prefers-reduced-motion (the elements carry
    no opacity:0 base outside this block).

    1. Overview strip + shop cards rise+fade in, staggered via --i (set per
       element in the template). animation-fill-mode: backwards holds the
       hidden state during the delay but does NOT persist afterwards, so the
       card :hover lift (translateY) keeps working once the entrance finishes.
    2. Each score bar grows from 0 to its real --sw-fill width, drawing the eye
       to the headline metric. Skipped for the "Analyzing…" empty state, whose
       track already shimmers.
*/
@media (prefers-reduced-motion: no-preference) {
    .sw-dashboard .sw-dash-enter {
        animation: sw-dash-rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) backwards;
        animation-delay: calc(var(--i, 0) * 70ms);
    }

    @keyframes sw-dash-rise {
        from { opacity: 0; transform: translateY(14px); }
        to   { opacity: 1; transform: none; }
    }

    .sw-dashboard .sw-score-bar:not(.sw-score-bar--empty) .sw-score-bar__fill {
        animation: sw-dash-fill 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.2s both;
    }

    @keyframes sw-dash-fill {
        from { width: 0; }
        to   { width: var(--sw-fill, 100%); }
    }

}

/* ── Auth split-screen ──
   Self-contained sign-in in the sw-auth2-* namespace. Formerly scoped --a2-* tokens (#957 S-4: mapped onto --sw-*)
   keep it from leaking elsewhere. The OTP pages keep the existing sw-auth-* styling. */
.sw-auth2 {
    /* #918 (J-15): the form panel follows the theme, and on the dark panel the
       fixed #1D4ED8 measured 2.6:1. The theme-aware brand text is AA on both. */

    display: grid;
    grid-template-columns: 1.05fr 1fr;
    min-height: calc(100dvh - var(--sw-navbar-height));
}

/* Brand panel - theme-locked dark on purpose */
.sw-auth2__aside {
    position: relative;
    overflow: hidden;
    display: flex;
    /* Top-anchor the brand panel so its logo stays at the same Y across auth
       steps whose form column differs in height (#442) - centering made it jump. */
    align-items: flex-start;
    padding: clamp(2.5rem, 5vw, 5rem);
    background: radial-gradient(120% 120% at 0% 0%, var(--sw-dark-bg), var(--sw-footer-bg) 60%);
    color: var(--sw-text);
}

.sw-auth2__aurora {
    position: absolute;
    inset: -30%;
    pointer-events: none;
    opacity: 0.9;
    filter: blur(12px);
    /* landing-aurora "Variant 2 · Vivid": blue + indigo + cyan blooms */
    background:
        radial-gradient(40% 40% at 18% 22%, rgba(59, 130, 246, 0.60), transparent 68%),
        radial-gradient(38% 38% at 84% 86%, rgba(99, 102, 241, 0.50), transparent 68%),
        radial-gradient(34% 34% at 62% 40%, rgba(34, 211, 238, 0.32), transparent 70%);
}

.sw-auth2__aside-inner {
    position: relative;
    z-index: 1;
    max-width: 30rem;
}

.sw-auth2__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 2.5rem;
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
}
.sw-auth2__brand-mark { width: 30px; height: 30px; color: var(--sw-brand-light); }
.sw-auth2__brand-accent { color: var(--sw-brand-light); }

.sw-auth2__headline {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.03em;
    margin-bottom: 1rem;
}
.sw-auth2__sub {
    max-width: 28rem;
    margin-bottom: 2.25rem;
    font-size: var(--sw-text-xl);
    line-height: 1.6;
    color: var(--sw-text-secondary);
}

.sw-auth2__points {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}
.sw-auth2__points li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--sw-text-md);
    color: var(--sw-text);
}
.sw-auth2__point-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: var(--sw-radius-btn);
    background: rgba(59, 130, 246, 0.22);
    color: var(--sw-brand-light);
}
.sw-auth2__point-icon svg { width: 13px; height: 13px; }

/* Form panel - adapts to light/dark via the shared tokens */
.sw-auth2__main {
    display: flex;
    /* Column, not the flex default row: the legal line (#640) is a sibling of
       the card, and as a row item it parked itself beside the form - on 390px
       that halved the form's width (#811). */
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: clamp(2rem, 5vw, 4rem) clamp(1.25rem, 4vw, 3rem);
    background: var(--sw-bg);
}
.sw-auth2__card {
    width: 100%;
    max-width: 25rem;
}
.sw-auth2__title {
    margin-bottom: 0.375rem;
    font-size: var(--sw-text-5xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
}
.sw-auth2__lead {
    margin-bottom: 2rem;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
}
/* Mechanics footnote under the benefit lead (#402/ADR-0009) - only present on
   pages that pair it with .sw-auth2__lead, so tighten the lead's own bottom
   margin there instead of touching the shared default used elsewhere. */
.sw-auth2__lead:has(+ .sw-auth2__intro-note) {
    margin-bottom: 0.375rem;
}
.sw-auth2__intro-note {
    margin-bottom: 2rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}
.sw-auth2__form {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
.sw-auth2__form .sw-form-label {
    display: block;
    margin-bottom: 0.4375rem;
}

/* Blue focus ring for the auth panel inputs */
.sw-auth2 .sw-form-control:focus {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

/* OTP segmented input: keep the existing sizing, just left-align it in the card */

/* ── OTP single-field code input ──
   A single autocomplete="one-time-code" field - the only reliable target for
   iOS Safari / SMS-&-email autofill (per-digit boxes break it). Styled large and
   letter-spaced so it still reads as a code field. */
.sw-otp-single {
    width: 100%;
    box-sizing: border-box;
    text-align: center;
    font-size: var(--sw-text-4xl);
    font-weight: 700;
    letter-spacing: 0.5em;
    text-indent: 0.5em; /* re-center against the trailing letter-spacing */
    font-variant-numeric: tabular-nums;
    padding: 0.875rem 0.5rem;
    border-radius: var(--sw-radius-card);
    border: 1px solid var(--sw-border);
    background: var(--sw-bg);
    color: var(--sw-text);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.sw-otp-single:focus {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
    outline: none;
}
.sw-auth2 .sw-otp-single:focus {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

.sw-auth2__submit {
    width: 100%;
    margin-top: 0.25rem;
    padding: 0.8125rem 1.25rem;
    border: none;
    border-radius: var(--sw-radius-btn);
    background: var(--sw-brand-strong);
    color: #fff;
    font: inherit;
    font-size: var(--sw-text-md);
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 8px 20px rgba(41, 80, 218, 0.30);
    transition: background 0.15s ease, transform 0.1s ease;
}
.sw-auth2__submit:hover { background: var(--sw-brand-strong-hover); }
.sw-auth2__submit:active { transform: translateY(1px); }

.sw-auth2__submit.sw-btn-filling {
    background: linear-gradient(to right, var(--sw-brand-strong-hover) 50%, var(--sw-brand-strong) 50%);
    background-size: 200% 100%;
    background-position: 100% 0;
    animation: sw-btn-fill 1000ms linear forwards;
}

/* Plan-nudge - deliberately subtle secondary action (a <button> styled as a
   plain text link) so Free stays the visually prominent, no-pressure choice. */

/* Plan nudge (onboarding/plan): compact plan blocks inside the auth card */

.sw-auth2__footer {
    margin-top: 1.75rem;
    text-align: center;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}
.sw-auth2__footer a {
    color: var(--sw-brand-text);
    font-weight: 600;
    text-decoration: none;
}
.sw-auth2__footer a:hover { text-decoration: underline; }
/* #407: resend button styled as the footer link + the cooldown countdown note */
.sw-auth2__resend-form { display: inline; }
.sw-auth2__resend {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--sw-brand-text);
    font-weight: 600;
    cursor: pointer;
}
.sw-auth2__resend:hover:not(:disabled) { text-decoration: underline; }
.sw-auth2__resend:disabled { color: var(--sw-text-muted); cursor: default; }
.sw-auth2__cooldown {
    margin: 0.35rem 0 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

/* Compact stand-in for the brand panel's value prop below 860px (#402) - a
   light-background block (matches the form panel), NOT a shrunk copy of the
   dark aside, which is styled for the split layout only. Hidden by default;
   shown only inside the mobile breakpoint below. */
.sw-auth2-mobile-value {
    display: none;
}

/* Below 860px: drop the brand panel, center the form */
@media (max-width: 860px) {
    .sw-auth2 {
        grid-template-columns: 1fr;
        /* Only the form row takes the leftover viewport height. With two auto
           rows the value block stretched as well and opened a fold-sized gap
           above the form (#811). */
        grid-template-rows: auto 1fr;
    }
    .sw-auth2__aside { display: none; }
    /* Top-anchored on mobile: centering left a fold-sized void between the
       value block and the form on tall phones (#811). */
    .sw-auth2__main { justify-content: flex-start; }

    .sw-auth2-mobile-value {
        display: block;
        padding: 1.75rem clamp(1.25rem, 4vw, 3rem) 1.5rem;
        background: var(--sw-bg);
        border-bottom: 1px solid var(--sw-border);
    }
    .sw-auth2-mobile-value__headline {
        margin: 0 0 0.75rem;
        font-size: var(--sw-text-xl);
        font-weight: 700;
        letter-spacing: -0.01em;
        color: var(--sw-text);
    }
    .sw-auth2-mobile-value__sub {
        margin: 0;
        font-size: var(--sw-text-md);
        line-height: 1.5;
        color: var(--sw-text-secondary);
    }
    /* Reuses .sw-firstrun__points (account/_firstrun.html.twig) for the
       checkmark list itself - identical list/li/svg styling, so only the
       component-level top margin needs overriding for this compact context. */
    .sw-auth2-mobile-value .sw-firstrun__points {
        margin-top: 0;
    }

}

/* Motion 1 - slow aurora drift on the brand panel (reads as "live monitoring").
   Motion 2 - form controls stagger in on load. Both reduced-motion gated;
   backwards fill holds the hidden state during the delay without persisting a
   transform afterwards, so the submit :active press still works. */
@media (prefers-reduced-motion: no-preference) {
    .sw-auth2__aurora {
        animation: sw-auth2-aurora 18s ease-in-out infinite alternate;
    }
    @keyframes sw-auth2-aurora {
        0%   { transform: translate3d(-4%, -2%, 0) scale(1.05); }
        100% { transform: translate3d(4%, 3%, 0) scale(1.15); }
    }

    .sw-auth2__field {
        animation: sw-auth2-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) backwards;
        animation-delay: calc(var(--i, 0) * 70ms + 80ms);
    }
    @keyframes sw-auth2-rise {
        from { opacity: 0; transform: translateY(10px); }
        to   { opacity: 1; transform: none; }
    }

}

/* ── Dashboard cockpit redesign ── */

/* Triage block - surfaces the worst shops. Tinted warning surface, no left
   accent border (house style), icon-led heading. */

/* Toolbar - section title + cockpit controls on one row. */

/* Dense list/table view (cockpit). */

/* a11y: the primary card/row action is a real 44px touch target. */

/* Dark mode: lift card borders so cards separate from the near-black surface. */

/* ── Dashboard portfolio-health hero ── */

/* Left: average-score ring + health distribution. */
.sw-rating-analyzing { background: var(--sw-text-muted); }

/* Right: triage / all-healthy panel. */

/* ── Dashboard, editorial (minimal, document-style) ── */

/* Lead: the portfolio number set large. */

/* Editorial controls - tab-underline filters + a quiet sort select. */

/* The list itself: hairline rows, no boxes. */

/* Editorial empty state. */

/* ── Dashboard B+C: bento cards + dense list ── */

/* Toolbar */
.sw-dash3-toolbar { display:flex; align-items:center; justify-content:space-between; gap:var(--sw-space-3); flex-wrap:wrap; margin-bottom:var(--sw-space-4); }
.sw-dash3-tools { display:flex; align-items:center; gap:.75rem; flex-wrap:wrap; }
.sw-dash3-chips { display:inline-flex; gap:.25rem; }
.sw-dash3-chip:hover { color:var(--sw-text); }
.sw-dash3-sort { padding:.375rem .625rem; border:1px solid var(--sw-border); border-radius:var(--sw-radius-control); background:var(--sw-bg); color:var(--sw-text); font:inherit; font-size:var(--sw-text-sm); cursor:pointer; }
.sw-dash3-toggle { display:inline-flex; border:1px solid var(--sw-border); border-radius:var(--sw-radius-control); overflow:hidden; }
.sw-dash3-toggle__btn { display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; background:var(--sw-bg); border:0; color:var(--sw-text-secondary); cursor:pointer; transition:.15s ease; }
.sw-dash3-toggle__btn + .sw-dash3-toggle__btn { border-left:1px solid var(--sw-border); }
.sw-dash3-toggle__btn:hover { background:var(--sw-bg-subtle); color:var(--sw-text); }
.sw-dash3-toggle__btn.is-active { background:var(--sw-brand-strong); color:#fff; }
.sw-dash3-toggle__btn svg { width:17px; height:17px; }
.sw-dash3-st { font-size:var(--sw-text-2xs); font-weight:700; padding:.1875rem .5rem; border-radius:var(--sw-radius-btn); flex-shrink:0; white-space:nowrap; }
.sw-dash3-st--up { background:var(--sw-success-tint); color:var(--sw-success-text); }
.sw-dash3-st--down { background:var(--sw-poor-tint); color:var(--sw-poor-text); }

/* Dense list / table (C) */
.sw-dash3-table { width:100%; border-collapse:collapse; font-size:var(--sw-text-base); }
.sw-dash3-table th.r, .sw-dash3-table td.r { text-align:right; }
.sw-dash3-table tbody td { padding:.875rem 1rem; border-bottom:1px solid var(--sw-border); vertical-align:middle; font-variant-numeric:tabular-nums; }
.sw-dash3-table tbody tr:last-child td { border-bottom:0; }
.sw-dash3-table tbody tr { transition:background .12s ease; }
.sw-dash3-table form { margin:0; }
.sw-dash3-table__dom { display:inline-flex; align-items:center; gap:.5rem; background:none; border:0; padding:0; font:inherit; font-weight:600; font-size:var(--sw-text-md); color:var(--sw-text); cursor:pointer; }
.sw-dash3-table__dom:hover { color:var(--sw-brand-text); }
.sw-dash3-table__sc { font-weight:700; font-size:var(--sw-text-lg); }
.sw-dash3-table__sc--good { color:var(--sw-success-text); }
.sw-dash3-table__sc--moderate { color:var(--sw-warning-text); }
.sw-dash3-table__sc--poor { color:var(--sw-poor-text); }
.sw-dash3-table__sc--analyzing { color:var(--sw-text-muted); }
.sw-dash3-muted { color:var(--sw-text-muted); }
.sw-dash3-spark { display:inline-flex; align-items:flex-end; gap:2px; height:18px; }
.sw-dash3-spark i { width:4px; background:var(--sw-border); border-radius:1px; }

/* Dark mode: lift surface borders off the near-black background. */

@media (max-width: 767.98px) {
    .sw-dash3-table__hide { display:none; }

}

/* ── Teams page (/account/teams) ── */

/* Agency view - compact management layout */
.sw-teams-page {
    padding-bottom: var(--sw-space-6);
}

/* Invite bar - visual styles moved to .sw-invite-card in the Teams block (FE-23).
   The .sw-teams-invite-bar class is kept in the template for test-selector compatibility. */


@media (max-width: 767.98px) {
    .sw-teams-invite-row {
        flex-wrap: wrap;
    }
    .sw-teams-invite-field--email,
    .sw-teams-invite-field--role {
        flex: 1 1 100%;
    }
    .sw-teams-invite-row .sw-btn {
        width: 100%;
    }

}

/* ── Analytics Redesign ── */

/* Page header */

/* Analyzing progress bar */
.sw-analyzing-bar { display:flex; align-items:center; gap:.75rem; padding:.5rem 0 .875rem; }
.sw-analyzing-bar[hidden] { display:none; }
.sw-analyzing-bar__track { flex:1; height:4px; border-radius:var(--sw-radius-btn); background:var(--sw-bg-subtle); overflow:hidden; }
.sw-analyzing-bar__fill { display:block; height:100%; border-radius:var(--sw-radius-btn); background:var(--sw-brand); transition:width .4s ease-out; }
/* Indeterminate: no fake percentage - a segment slides across to signal "work in progress" honestly. */
.sw-analyzing-bar__fill--indeterminate { width:35%; transition:none; animation:sw-indeterminate 1.4s ease-in-out infinite; }
@keyframes sw-indeterminate {
    0%   { transform:translateX(-120%); }
    100% { transform:translateX(320%); }
}
.sw-analyzing-bar__text { font-size:var(--sw-text-sm); color:var(--sw-text-secondary); white-space:nowrap; flex-shrink:0; }
/* .sw-analyzing-bar[hidden] already hides via the CSS rule above; no --done class needed. */

/* Overview block */

@media (prefers-reduced-motion: reduce) {
    .sw-analyzing-bar__fill { transition:none; }
    /* Static, honest fallback when motion is reduced: a calm partial fill, no sliding. */
    .sw-analyzing-bar__fill--indeterminate { animation:none; transform:none; width:45%; opacity:.7; }

}
/* ── Uptime: up_protected state ── */
.sw-dash3-st--protected { background:var(--sw-warning-tint); color:var(--sw-warning-text); }
.sw-badge-protected { background:var(--sw-warning-tint); color:var(--sw-warning-text); border-color:transparent; }
html.sw-dark .sw-dash3-st--protected { background:var(--sw-warning-tint); color:var(--sw-warning-text); }
html.sw-dark .sw-badge-protected { background:var(--sw-warning-tint); color:var(--sw-warning-text); }

/* ── Guided Activation (Q1-Q4 + G1) ── */

/* Shared card shell */
.sw-nba { display:flex; align-items:flex-start; gap:1rem; padding:1.25rem 1.5rem; border:1px solid var(--sw-border); border-radius:var(--sw-radius-card, 12px); background:var(--sw-bg); margin-bottom:var(--sw-space-5); }

/* Onboarding empty state (Q2) */
.sw-nba--onboarding { background:var(--sw-brand-tint); border-color:var(--sw-brand-light); flex-direction:column; gap:.875rem; }
.sw-nba--onboarding .sw-nba__icon { width:40px; height:40px; background:var(--sw-brand-tint); border-radius:var(--sw-radius-inline); display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--sw-brand-text); }
.sw-nba--onboarding .sw-nba__icon svg { width:22px; height:22px; }

/* Analyzing state (Q3) */
.sw-nba--analyzing { background:var(--sw-bg-subtle); border-style:dashed; }
.sw-nba--analyzing .sw-nba__icon { width:36px; height:36px; background:var(--sw-brand-tint); border-radius:var(--sw-radius-control); display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--sw-brand-text); }
.sw-nba--analyzing .sw-nba__icon svg { width:20px; height:20px; }
.sw-nba__progress { margin-top:.75rem; }

/* Perfect state */
.sw-nba--perfect { background:var(--sw-success-tint, #f0fdf4); border-color:var(--sw-success, #22c55e); }
.sw-nba--perfect .sw-nba__icon { width:36px; height:36px; background:var(--sw-success-tint, #f0fdf4); border-radius:var(--sw-radius-control); display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--sw-success-dark, #16a34a); }
.sw-nba--perfect .sw-nba__icon svg { width:20px; height:20px; }

/* Actions state (G1) - "coaching plan" look (2026-08-04): the dense card
   stack read as a technical audit log. The plan now breathes: no outer card,
   a reading column, numbered steps on a rail, advice as flowing prose. */
.sw-nba--actions { flex-direction:column; gap:1.5rem; background:transparent; border:none; padding:0; max-width:820px; }
.sw-nba__head { display:flex; align-items:flex-start; gap:1rem; }
.sw-nba__head-icon { width:46px; height:46px; background:var(--sw-brand-tint); border-radius:var(--sw-radius-card); display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--sw-brand-text); }
.sw-nba__head-icon svg { width:22px; height:22px; }
.sw-nba--actions .sw-nba__title { font-size:var(--sw-text-3xl); letter-spacing:-.02em; }
.sw-nba--actions .sw-nba__sub { font-size:var(--sw-text-md); }

/* Shared text */
.sw-nba__body { flex:1; min-width:0; }
.sw-nba__title { font-size:var(--sw-text-md); font-weight:600; color:var(--sw-text); margin:0 0 .25rem; letter-spacing:-.01em; }
.sw-nba__sub { font-size:var(--sw-text-base); color:var(--sw-text-secondary); margin:0; line-height:1.5; }

/* Onboarding value points */
.sw-nba__points { list-style:none; padding:0; margin:.625rem 0 0; display:flex; flex-direction:column; gap:.375rem; }
.sw-nba__points li { display:flex; align-items:flex-start; gap:.5rem; font-size:var(--sw-text-base); color:var(--sw-text-secondary); }
.sw-nba__points li svg { width:14px; height:14px; color:var(--sw-brand-text); flex-shrink:0; margin-top:3px; }

/* Onboarding inline form (Q1) */
.sw-nba__cta { margin-top:.25rem; }
.sw-nba__inline-form { display:flex; gap:.5rem; flex-wrap:wrap; }
.sw-nba__domain-input { flex:1; min-width:200px; padding:.5rem .875rem; border:1px solid var(--sw-border); border-radius:var(--sw-radius-btn); font-size:var(--sw-text-md); background:var(--sw-bg); color:var(--sw-text); outline:none; }
.sw-nba__domain-input:focus { border-color:var(--sw-brand-text); box-shadow: 0 0 0 2px var(--sw-focus-ring); }
.sw-nba__domain-input::placeholder { color:var(--sw-text-muted); }

/* Action list (G1) - numbered coaching steps */
.sw-nba__list { list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:1.25rem; width:100%; }
.sw-dashboard { --sw-nba-rail:44px; --sw-nba-rail-gap:1rem; }
.sw-nba-step { display:grid; grid-template-columns:var(--sw-nba-rail, 44px) 1fr; gap:var(--sw-nba-rail-gap, 1rem); position:relative; }
.sw-nba-step__num { width:38px; height:38px; border-radius:var(--sw-radius-btn); display:grid; place-items:center; background:var(--sw-brand-strong); color:#fff; font-size:var(--sw-text-lg); font-weight:700; margin-top:1.5rem; z-index:1; }
/* Rail connecting the steps - the "journey" line */
.sw-nba-step::before { content:""; position:absolute; left:18.5px; top:0; bottom:-1.25rem; width:2px; background:var(--sw-border); }
.sw-nba-step:first-child::before { top:1.5rem; }
.sw-nba-step:last-child::before { bottom:auto; height:2.75rem; }
.sw-nba-step:first-child:last-child::before { display:none; }
.sw-nba__item { padding:1.625rem 1.875rem; background:var(--sw-bg); border:1px solid var(--sw-border); border-radius:var(--sw-radius-panel); min-width:0; }
.sw-nba__item-impact { margin-bottom:.75rem; }
.sw-nba__impact-badge { display:inline-block; font-size:var(--sw-text-xs); font-weight:600; padding:.25rem .7rem; border-radius:var(--sw-radius-btn); }
/* Tinted like .sw-badge-brand: solid brand blue is reserved for CTAs, a label in it read as a button (2026-09-29). */
.sw-nba__impact-badge--headline { background:var(--sw-brand-tint); color:var(--sw-brand-text); border:1px solid rgba(59, 130, 246, 0.3); }
.sw-nba__impact-badge--detail { background:var(--sw-bg-subtle); border:1px solid var(--sw-border); color:var(--sw-text-secondary); }
.sw-nba__item-message { font-size:var(--sw-text-xl); font-weight:650; letter-spacing:-.01em; color:var(--sw-text); margin:0 0 1rem; line-height:1.45; }
/* Advice as flowing prose - no nested box-in-box */
.sw-nba__advice { margin:0 0 1.125rem; display:flex; flex-direction:column; gap:.75rem; }
.sw-nba__advice-row { font-size:var(--sw-text-md); color:var(--sw-text-secondary); margin:0; line-height:1.7; }
.sw-nba__advice-row strong { display:block; color:var(--sw-brand-light); font-weight:650; font-size:var(--sw-text-sm); text-transform:uppercase; letter-spacing:.04em; margin-bottom:.2rem; }
.sw-nba__item-meta { display:flex; align-items:center; justify-content:space-between; gap:.75rem; flex-wrap:wrap; border-top:1px solid var(--sw-border); padding-top:1rem; }
.sw-nba__item-shop { font-size:var(--sw-text-sm); color:var(--sw-text-muted); font-weight:500; }
.sw-nba__item-link { font-size:var(--sw-text-base); font-weight:600; color:var(--sw-brand-text); text-decoration:none; display:inline-flex; align-items:center; gap:.4rem; padding:.45rem 1.1rem; border:1px solid var(--sw-border); border-radius:var(--sw-radius-btn); transition:background .15s ease, border-color .15s ease; }
.sw-nba__item-link svg { width:13px; height:13px; }
.sw-nba__item-link:hover { text-decoration:none; background:var(--sw-brand-tint); border-color:var(--sw-brand-light); }

/* Free plan progressive reveal ("Show me the next recommendation") */
.sw-nba__reveal-form { border-top:1px solid var(--sw-border); padding-top:.625rem; margin-top:.125rem; }

/* ── Free "ladder" (single-shop Free, ADR-0005 Variant A "Wow") ──
   Visual source of truth: public/_mockups/nba/free-a.html (sw-nba-* classes). */

/* Progress meter above the N slots */
.sw-nba-progress { margin-bottom:1rem; }
.sw-nba-progress__track { display:flex; gap:4px; height:6px; margin-bottom:.5rem; }
.sw-nba-progress__seg { flex:1; border-radius:var(--sw-radius-btn); background:var(--sw-border); transition:background 240ms cubic-bezier(0.22,1,0.36,1); }
.sw-nba-progress__seg.is-done { background:var(--sw-success); }
.sw-nba-progress__seg.is-frontier { background:var(--sw-brand); animation:sw-nba-pulse 1.8s ease-in-out infinite; }
@keyframes sw-nba-pulse { 0%,100% { opacity:1; } 50% { opacity:.45; } }
.sw-nba-progress__caption { font-size:var(--sw-text-md); color:var(--sw-text-secondary); margin:0; font-weight:500; }
.sw-nba-progress__caption strong { color:var(--sw-text); font-weight:700; }

/* Slot list */
.sw-nba-slots { list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:1.25rem; width:100%; }
.sw-nba-slot { position:relative; }

/* Revealed slot = real .sw-nba__item, plus a small "Unlocked" corner marker */
.sw-nba-slot--revealed .sw-nba__item { position:relative; padding-right:7rem; }
.sw-nba-slot__done { position:absolute; top:1.25rem; right:1.5rem; display:inline-flex; align-items:center; gap:.25rem; font-size:var(--sw-text-2xs); font-weight:700; color:var(--sw-success-text); background:var(--sw-success-tint); border-radius:var(--sw-radius-btn); padding:.15rem .5rem; }
.sw-nba-slot__done svg { width:11px; height:11px; }

/* Locked card: same card chrome as a revealed .sw-nba__item, but the fix text
   is replaced by a blurred skeleton (frosted glass over "there's content
   here"). Category, impact and points stay legible - ADR-0005 allows teasing
   those; only the actual fix is withheld, and no real message text is ever in
   the DOM (see HiddenActionTeaser). */
.sw-nba-locked-card { position:relative; }
.sw-nba-locked-card .sw-nba__item-impact { display:flex; align-items:center; gap:.5rem; }
.sw-nba-locked-pts { margin-left:auto; font-size:var(--sw-text-xs); font-weight:700; color:var(--sw-brand-text); background:var(--sw-brand-tint); border-radius:var(--sw-radius-btn); padding:.15rem .55rem; white-space:nowrap; }
.sw-nba-locked-skel { display:flex; flex-direction:column; gap:.55rem; margin:.85rem 0 .95rem; filter:blur(2.5px); opacity:.7; user-select:none; }
.sw-nba-skel-bar { height:.7rem; border-radius:var(--sw-radius-btn); background:linear-gradient(90deg,var(--sw-border),var(--sw-bg-subtle)); }
.sw-nba-locked-hint { display:inline-flex; align-items:center; gap:.375rem; font-size:var(--sw-text-xs); font-weight:600; color:var(--sw-text-muted); }
.sw-nba-locked-hint svg { width:14px; height:14px; }
.sw-nba-slot__unlock { display:inline-flex; align-items:center; justify-content:center; gap:.45rem; white-space:nowrap; }
.sw-nba-slot__unlock svg { width:16px; height:16px; flex-shrink:0; }
.sw-nba-slot__unlock[disabled] { opacity:.75; cursor:progress; }

/* Queued cards sit a touch back so the frontier (the one with the Unlock
   button) stays the single active step. */
.sw-nba-slot--queued .sw-nba-locked-card { opacity:.9; }

/* Upgrade slot (permanent once beyond budget) - deliberately NOT styled like a
   locked card: solid tint, no blur, no dashed border - it's an offer, not a
   mystery box. */

@media (prefers-reduced-motion:reduce) {
    .sw-nba-progress__seg.is-frontier { animation:none; }

}

/* Q4 Headline hint tooltip button */
.sw-headline-hint { background:none; border:none; padding:2px; cursor:pointer; color:var(--sw-text-muted); display:inline-flex; align-items:center; margin-left:.25rem; border-radius:var(--sw-radius-xs); }
.sw-headline-hint svg { width:16px; height:16px; }
.sw-headline-hint:hover { color:var(--sw-brand-text); }
.sw-headline-hint:focus-visible { outline:2px solid var(--sw-brand-text); outline-offset:2px; }
/* Click-to-open panel for the "?" hint (hint_controller.js): a title tooltip alone
   never shows on touch and only after a hover delay on desktop. */
.sw-hint { position: relative; display: inline-flex; }
.sw-hint__panel {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 20;
    width: max-content; max-width: min(22rem, 80vw);
    padding: .625rem .75rem; border-radius: var(--sw-radius-control);
    background: var(--sw-bg-elevated, var(--sw-bg)); border: 1px solid var(--sw-border);
    box-shadow: var(--sw-shadow-lg);
    font-size: var(--sw-text-sm); font-weight: 400; line-height: 1.45; color: var(--sw-text); text-align: left; white-space: normal;
}

/* Dark mode */
html.sw-dark .sw-nba { border-color:var(--sw-border); background:var(--sw-bg); }
html.sw-dark .sw-nba--onboarding { background:rgba(59,130,246,.08); border-color:rgba(59,130,246,.3); }
html.sw-dark .sw-nba--analyzing { background:var(--sw-bg-subtle); }
html.sw-dark .sw-nba--perfect { background:rgba(34,197,94,.08); border-color:rgba(34,197,94,.3); }
html.sw-dark .sw-nba__item { background:var(--sw-bg-subtle); }
html.sw-dark .sw-nba__impact-badge--detail { background:var(--sw-bg); border-color:var(--sw-border); }
html.sw-dark .sw-nba__domain-input { background:var(--sw-bg-subtle); color:var(--sw-text); border-color:var(--sw-border); }

/* Mobile */
@media (max-width: 767.98px) {
    .sw-nba { padding:1rem; gap:.75rem; }
    .sw-nba__inline-form { flex-direction:column; }
    .sw-nba__domain-input { min-width:0; width:100%; }
    .sw-nba__inline-form .sw-btn { width:100%; }
    .sw-nba__item-meta { flex-direction:column; align-items:flex-start; }
    .sw-nba__reveal-form .sw-btn { width:100%; }

}

/* ── First-run panel ── */
/* Rendered when the user has no shops (shopData is empty).
   Fills the content column of sw-app-layout, vertically centred.
   Uses only --sw-* design tokens - works in light and dark themes. */

.sw-firstrun {
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    padding: var(--sw-space-8) var(--sw-space-5);
}

.sw-firstrun__inner {
    width: 100%;
    max-width: 520px;
    text-align: left;
}

.sw-firstrun__heading {
    font-size: var(--sw-text-3xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin: 0 0 var(--sw-space-2);
    text-wrap: balance;
}

.sw-firstrun__sub {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.55;
    margin: 0 0 var(--sw-space-5);
    max-width: 44ch;
}

.sw-firstrun__points {
    list-style: none;
    padding: 0;
    margin: var(--sw-space-5) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-2);
}

.sw-firstrun__points li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    line-height: 1.45;
}

.sw-firstrun__points li svg {
    width: 15px;
    height: 15px;
    color: var(--sw-brand-text);
    flex-shrink: 0;
    margin-top: 2px;
}

/* .sw-firstrun__form / __input / __submit / __form-wrap .sw-url-status and
   the shared mobile (<480px) rule are declared below, combined with their
   .sw-empty-add__* equivalents (#387) so the two panels share one set of
   rules for the identical mechanics. */

/* ── Empty add-shop state (shared across Insights pages) ── */
/* _empty_add_shop.html.twig (#387) - the "no shop yet" prompt reused on
   history/competitors/analytics/techstack. A compact card (unlike the
   full-page .sw-firstrun panel) since these pages already render their own
   header above it. Shares the input/button/status mechanics with
   .sw-firstrun via combined selectors below so both stay visually and
   behaviourally identical. Icon chip: tinted background, never a
   brand-coloured left border (founder rule). */

.sw-empty-add {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: var(--sw-space-8) var(--sw-space-5);
}

.sw-empty-add__icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--sw-space-4);
}

.sw-empty-add__icon svg {
    width: 28px;
    height: 28px;
}

.sw-empty-add__heading {
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin: 0 0 var(--sw-space-2);
    text-wrap: balance;
}

.sw-empty-add__sub {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.55;
    margin: 0 0 var(--sw-space-5);
    max-width: 44ch;
}

.sw-empty-add__form-wrap {
    width: 100%;
    max-width: 460px;
}

.sw-empty-add__readonly {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0;
}

.sw-firstrun__form,
.sw-empty-add__form {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-3);
}

@media (min-width: 480px) {
    .sw-firstrun__form,
    .sw-empty-add__form {
        flex-direction: row;
        align-items: flex-start;
        flex-wrap: wrap; /* allows .sw-url-status to span full width below */
    }

}

.sw-firstrun__input,
.sw-empty-add__input {
    flex: 1;
    min-width: 200px;
    height: 44px;
    padding: 0 1rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    font-size: var(--sw-text-md);
    font-family: inherit;
    background: var(--sw-bg);
    color: var(--sw-text);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.sw-firstrun__input:focus,
.sw-empty-add__input:focus {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

.sw-firstrun__input::placeholder,
.sw-empty-add__input::placeholder {
    color: var(--sw-text-muted);
}

.sw-firstrun__submit,
.sw-empty-add__submit {
    height: 44px;
    white-space: nowrap;
    flex-shrink: 0;
}

/* url-status spans full width below the input + button row */
.sw-firstrun__form-wrap .sw-url-status,
.sw-empty-add__form-wrap .sw-url-status {
    display: block;
    width: 100%;
    font-size: var(--sw-text-base);
    min-height: 1.25rem; /* reserve space so layout doesn't jump */
    text-align: left;
}

/* Mobile (<480px): stack input + button, both full width */
@media (max-width: 479.98px) {
    .sw-firstrun,
    .sw-empty-add {
        padding: var(--sw-space-6) var(--sw-space-4);
    }

    .sw-firstrun__input,
    .sw-empty-add__input {
        width: 100%;
    }

    .sw-firstrun__submit,
    .sw-empty-add__submit {
        width: 100%;
    }

}

/* ── Account Facelift ── */

/* Shared page header - replaces sw-shops-header, sw-teams-header,
   sw-analytics-page-header, and bare <h1> + .sw-dash-sub combos
   across all account sub-pages. */
.sw-account-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sw-space-4);
    margin-bottom: var(--sw-space-6);
}

.sw-account-header__left {
    min-width: 0;
}

/* Double class (0,2,0) so the unified title always wins over legacy
   wrapper-scoped rules like `.sw-dashboard h1` (0,1,1) - without those,
   the title font-size/margin jumped between sw-dashboard and sw-shops pages. */
.sw-account-header .sw-account-header__title {
    font-size: var(--sw-text-3xl);
    font-weight: 700;
    letter-spacing: -.02em;
    margin: 0;
    color: var(--sw-text);
    /* #1087: a long title (a shop domain, a page URL) wraps, it is never cut. */
    overflow-wrap: anywhere;
}

.sw-account-header__sub {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0.25rem 0 0;
    max-width: 72ch;
}

/* #1087: the account's two content widths. The header always spans the column;
   what sits below it is either the full column (default, no class) or a form at
   640px. Replaces the 1024/880/640/560/480 patchwork. */
.sw-page-form { max-width: 640px; }
.seta-wrap { margin: 0; }

.sw-account-header__actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--sw-space-3);
    /* A badge + a button (competitors header, #537) can outgrow the content
       column at any width once the sidebar still shows (up to 767.98px) -
       wrap instead of overflowing rather than gating this to one breakpoint. */
    flex-wrap: wrap;
}

@media (max-width: 575.98px) {
    .sw-account-header {
        flex-direction: column;
        gap: var(--sw-space-3);
    }
    .sw-account-header__actions {
        width: 100%;
    }

}

/* Section-rhythm title - replaces sw-team-section-title and
   sw-profile-section-label with a single consistent token. */
.sw-account-section-title {
    margin: 0 0 var(--sw-space-4);
}


/* Billing 3-zone spacing */
.sw-billing-zone + .sw-billing-zone {
    margin-top: var(--sw-space-8);
}

/* Billing plan-selection bento: current-plan selection ring */
.sw-billing-card--selected {
    border-color: var(--sw-brand) !important;
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

/* Billing plan-selection bento: target/upgrade plan gradient tint */


/* Inline form field hint / note below a read-only value. */

/* ── Add Shop ── */

/* Card wrapper: constrain max-width so the single-column form
   doesn't stretch across a wide content area. */
.sw-shop-add-card {
    max-width: 640px;
    padding: 0;
    overflow: hidden;
}

/* ── Intro band ── */

/* ── Form body ── */
.sw-shop-form {
    padding: var(--sw-space-5) var(--sw-space-6);
}

/* Manage pages: a polished disclosure inside a card. The summary is a proper
   header row (icon + title + rotating chevron) instead of a bare bold line with
   the default triangle; the body reveals below a thin separator. */
.sw-pages-manage__summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: var(--sw-space-3);
}
.sw-pages-manage__summary::-webkit-details-marker {
    display: none;
}
.sw-pages-manage__icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border-radius: var(--sw-radius-inline);
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
}
.sw-pages-manage__head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.sw-pages-manage__title {
    font-weight: 600;
    font-size: var(--sw-text-xl);
    color: var(--sw-text);
}
.sw-pages-manage__chevron {
    margin-left: auto;
    flex-shrink: 0;
    color: var(--sw-text-muted);
    transition: transform 0.15s ease;
}
.sw-pages-manage[open] .sw-pages-manage__chevron {
    transform: rotate(180deg);
}
.sw-pages-manage__body {
    margin-top: var(--sw-space-4);
    padding-top: var(--sw-space-4);
    border-top: 1px solid var(--sw-border);
}
/* The form keeps its .sw-shop-form marker class, but the disclosure body
   already supplies padding, so drop the form's own to avoid double insets. */
.sw-pages-manage__body .sw-shop-form {
    padding: 0;
}

/* Domain input + button: side-by-side on ≥480px, stacked below. */

/* ── Unified URL bar: globe + input + status + submit as one control ── */
.sw-shop-url-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.4rem 0.4rem 0.85rem;
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.sw-shop-url-bar:focus-within {
    border-color: var(--sw-brand-text);
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

.sw-shop-url-bar-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--sw-text-muted);
}

.sw-shop-url-bar-input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    padding: 0.55rem 0;
    font-size: var(--sw-text-lg);
    font-family: inherit;
    color: var(--sw-text);
}

.sw-shop-url-bar-input::placeholder { color: var(--sw-text-muted); }

.sw-shop-url-bar-btn {
    flex-shrink: 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
}

@media (max-width: 519.98px) {
    .sw-shop-url-bar {
        flex-wrap: wrap;
        padding: 0.85rem;
    }
    .sw-shop-url-bar-input { width: 100%; flex-basis: calc(100% - 1.75rem); }
    .sw-shop-url-bar-btn { width: 100%; justify-content: center; }

}

/* ── "What gets checked" value chips ── */
.sw-shop-add-chips-lead {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin: var(--sw-space-3) 0 0.5rem;
}

.sw-shop-add-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 var(--sw-space-4);
}

.sw-shop-add-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    padding: 0.35rem 0.75rem;
}

.sw-shop-add-chip svg {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    color: var(--sw-brand-text);
}

/* "What gets checked" note */

/* Metered billing notice - brand-tinted, informational */
.sw-shop-metered-note--info {
    background: var(--sw-brand-tint);
    border-color: var(--sw-brand-light);
    margin-bottom: var(--sw-space-4);
}

.sw-shop-metered-note--info svg {
    color: var(--sw-brand-text);
}

html.sw-dark .sw-shop-metered-note--info {
    background: var(--sw-brand-tint);
    border-color: rgba(59, 130, 246, 0.3);
}

/* "optional" label inside the disclosure summary */

/* Disclosure section gets a subtle inset feel */


/* ── Add Shop - mobile ── */
@media (max-width: 767.98px) {
    .sw-shop-add-card {
        max-width: 100%;
    }

    .sw-shop-form {
        padding: var(--sw-space-4) var(--sw-space-4);
    }

    /* Stack input above button on narrow screens */


}

/* Bento row 2: three equal sub-cards */

/* Status card (2fr) */

/* Cost breakdown dl */

/* Charge card (1fr) */

/* Clickable sub-cards (row 2) */

/* Canceled/warning banner - tinted bg, no left-border */
/* The canceled, pending-payment and pending-upgrade messages are .sw-notice
   instances now (#819); their own classes stay as hooks for tests and for the
   one-off tweak below. */
.sw-billing-canceled-banner .sw-notice__title { font-weight: 500; }

/* Breadcrumb - every account page below another one, via
   _partials/_breadcrumb.html.twig (founder request 2026-09-28) */
.sw-breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .375rem;
    list-style: none;
    padding: 0;
    margin: 0 0 var(--sw-space-4);
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}
.sw-breadcrumb li { display: inline-flex; align-items: center; min-width: 0; }
.sw-breadcrumb li + li::before {
    content: '/';
    color: var(--sw-text-muted);
    margin-right: 0.375rem;
}
.sw-breadcrumb a {
    color: var(--sw-text-secondary);
    text-decoration: none;
    border-radius: var(--sw-radius-xs);
}
.sw-breadcrumb a:hover {
    color: var(--sw-brand-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.sw-breadcrumb a:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; }
.sw-breadcrumb [aria-current="page"] {
    color: var(--sw-text);
    font-weight: 500;
    overflow-wrap: anywhere;
}
@media (max-width: 767.98px) {
    .sw-breadcrumb a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Dark mode overrides for billing bento */

/* Usage meter text helper */

/* ── Onboarding ── */

.sw-form-hint {
    display: block;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    margin-top: 0.25rem;
    margin: 0;
}

.sw-form-error {
    display: block;
    font-size: var(--sw-text-sm);
    color: var(--sw-danger-dark);
    margin-top: 0.25rem;
}

/* Tile look scoped to consent checkboxes (those using .sw-form-check-input),
   so plain .sw-form-check rows elsewhere (e.g. admin toggles) are untouched. */
.sw-form-check:has(.sw-form-check-input) {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    padding: 0.75rem 0.875rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-inline);
    background: var(--sw-bg-subtle);
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.sw-form-check:has(.sw-form-check-input):hover {
    border-color: var(--sw-brand);
}

/* Tile lights up once consent is given. */
.sw-form-check:has(.sw-form-check-input:checked) {
    border-color: var(--sw-brand-strong);
    background: var(--sw-brand-tint);
}

/* Custom checkbox: branded box + crisp white checkmark.
   Selector is scoped to out-specify the older `.sw-form-check input[type=checkbox]`. */
.sw-form-check input.sw-form-check-input {
    appearance: none;
    -webkit-appearance: none;
    flex-shrink: 0;
    width: 1.2rem;
    height: 1.2rem;
    margin: 0;
    cursor: pointer;
    border: 2px solid var(--sw-border);
    border-radius: var(--sw-radius-sm);
    background: var(--sw-bg);
    display: grid;
    place-content: center;
    accent-color: initial;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.sw-form-check-input::after {
    content: "";
    width: 0.34rem;
    height: 0.62rem;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translateY(-1px);
    opacity: 0;
    transition: opacity 0.12s ease;
}

.sw-form-check-input:checked {
    background: var(--sw-brand-strong);
    border-color: var(--sw-brand-strong);
}

.sw-form-check-input:checked::after {
    opacity: 1;
}

.sw-form-check-input:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--sw-focus-ring);
}

.sw-form-check-label {
    cursor: pointer;
    line-height: 1.4;
}

.sw-form-check-label a {
    color: var(--sw-brand-text);
    font-weight: 500;
}

.sw-form-check--error {
    outline: 2px solid var(--sw-danger);
    outline-offset: 3px;
    border-radius: var(--sw-radius-xs);
    padding: 0.35rem;
}

.sw-onboarding-invite-box {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    background: var(--sw-brand-tint);
    border: 1px solid var(--sw-brand);
    border-radius: var(--sw-radius-inline);
    padding: 0.875rem 1rem;
    color: var(--sw-text);
}

.sw-onboarding-invite-box svg {
    color: var(--sw-brand-text);
    flex-shrink: 0;
    margin-top: 0.15rem;
}

.sw-onboarding-invite-box p {
    margin: 0;
    font-size: var(--sw-text-base);
    line-height: 1.5;
    color: var(--sw-text);
}

/* Re-consent modal - blocking, no close button */
.sw-modal-overlay--blocking {
    cursor: default;
}

.sw-modal--terms {
    max-width: 460px;
    text-align: center;
}

.sw-modal--terms .sw-modal-icon {
    width: 52px;
    height: 52px;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    color: var(--sw-text-secondary);
    margin-bottom: 1rem;
}

.sw-modal--terms .sw-modal-actions {
    justify-content: flex-start;
    width: auto;
}

.sw-modal--terms .sw-modal-actions .sw-btn {
    width: auto;
}

/* The terms modal centers its content, but the consent tile must stay a proper
   left-aligned "checkbox + label" row: without this the label (inheriting the
   base .sw-form-check flex-wrap:wrap + the modal's text-align:center) wraps onto
   its own centered line and the checkbox is stranded top-left (#609). */
.sw-modal--terms .sw-form-check {
    text-align: left;
    align-items: flex-start;
    flex-wrap: nowrap;
}

.sw-modal--terms .sw-form-check .sw-form-check-label {
    flex: 1;
}

/* Inline validity state */
.sw-form-control.is-invalid {
    border-color: var(--sw-danger);
}

.sw-form-control.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}

/* ── Billing Ledger View (Variant B) ── */

/* Ledger grid: statement on left, sidebar on right */
.sw-billing-ledger-grid {
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 1.25rem;
    align-items: start;
}

.sw-billing-ledger-left {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* Outstanding banner */
/* One notice family for account status messages (#819). The anatomy is fixed -
   icon tile, title, optional sub line, one action - and a tone only swaps the
   three colour tokens, all of which are theme-aware, so dark mode needs no
   overrides of its own. Grown out of the outstanding-balance banner, which had
   this build already while three neighbours on the same page each had another. */
.sw-notice {
    --notice-fg: var(--sw-brand-text);
    --notice-bg: var(--sw-brand-tint);
    --notice-accent: var(--sw-brand);
    display: flex;
    /* #911: top, not centre - beside a four-line notice the tile sat halfway
       down instead of at the title. The action keeps its centre below. */
    align-items: flex-start;
    gap: 1rem;
    padding: 1rem 1.25rem;
    background: var(--notice-bg);
    border: 1px solid color-mix(in srgb, var(--notice-accent) 30%, transparent);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    margin-bottom: 1.25rem;
}
.sw-notice--warning {
    --notice-fg: var(--sw-warning-text);
    --notice-bg: var(--sw-warning-tint);
    --notice-accent: var(--sw-warning);
}
.sw-notice--danger {
    --notice-fg: var(--sw-poor-text);
    --notice-bg: var(--sw-danger-tint);
    --notice-accent: var(--sw-danger);
}

.sw-notice__icon {
    width: 34px;
    height: 34px;
    /* Centred on the title line (0.9375rem at the inherited line-height 1.6). */
    margin-top: calc((0.9375rem * 1.6 - 34px) / 2);
    flex-shrink: 0;
    background: color-mix(in srgb, var(--notice-accent) 15%, transparent);
    border-radius: var(--sw-radius-inline);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--notice-fg);
}

.sw-notice__body {
    flex: 1;
    min-width: 0;
}

.sw-notice__title {
    font-size: var(--sw-text-md);
    font-weight: 600;
    color: var(--notice-fg);
    margin: 0;
}

.sw-notice__sub {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin: 0.125rem 0 0;
}

/* The cancel page sets its warning apart from the plan details below it - it
   asks for a decision, not for a glance (#830). */
.sw-notice--roomy { margin-bottom: var(--sw-space-5); }

/* The action is whatever the caller put in the block - a link, a button or a
   form around one. It never shrinks and never wraps under the body. */
.sw-notice > a,
.sw-notice > form,
.sw-notice > .sw-btn {
    flex-shrink: 0;
    align-self: center;
}

/* Styleguide only: three tones under each other in one example box. */
.sw-styleguide-block__example--stack { display: flex; flex-direction: column; gap: 0.75rem; }
.sw-styleguide-block__example--stack .sw-notice { margin-bottom: 0; }

/* Statement card */
.sw-statement {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    overflow: hidden;
}

.sw-statement__header {
    padding: 0.875rem 1.25rem;
    background: var(--sw-bg-subtle);
    border-bottom: 1px solid var(--sw-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.sw-statement__period {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

/* Line items */
.sw-line-item {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 0.5rem 1.5rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--sw-border);
}

.sw-line-item:last-of-type {
    border-bottom: none;
}

.sw-line-item__name {
    font-size: var(--sw-text-base);
    color: var(--sw-text);
}

.sw-line-item__sub {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    margin-top: 0.125rem;
}

.sw-line-item__amount {
    font-size: var(--sw-text-base);
    font-variant-numeric: tabular-nums;
    color: var(--sw-text);
    text-align: right;
    font-weight: 500;
    white-space: nowrap;
}

.sw-line-item__amount--muted {
    color: var(--sw-text-secondary);
    font-weight: 400;
}

/* Proration row - tinted bg, no border-left accent */
.sw-line-item--proration {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.75rem 1.25rem;
    background: var(--sw-warning-tint, rgba(245, 158, 11, 0.10));
    border-bottom: 1px solid rgba(245, 158, 11, 0.15);
}

.sw-line-item--proration .sw-line-item__amount {
    color: var(--sw-warning-text, #b45309);
    font-weight: 700;
    font-size: var(--sw-text-md);
}

/* Proration status badge */

/* Statement total row */
.sw-statement-total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    background: var(--sw-brand-tint);
    border-top: 1px solid rgba(59, 130, 246, 0.15);
}

.sw-statement-total__label {
    font-size: var(--sw-text-md);
    font-weight: 600;
    color: var(--sw-brand-text);
}

.sw-statement-total__amount {
    font-size: var(--sw-text-3xl);
    font-weight: 800;
    letter-spacing: -0.03em;
    color: var(--sw-brand-text);
    font-variant-numeric: tabular-nums;
}

.sw-statement-total__interval {
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text-muted);
    margin-left: 0.2em;
    letter-spacing: 0;
}

/* Inline invoices section */
.sw-billing-invoices-inline {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    overflow: hidden;
    box-shadow: var(--sw-shadow-sm);
}

.sw-billing-invoices-inline__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.875rem 1.25rem;
    background: var(--sw-bg-subtle);
    border-bottom: 1px solid var(--sw-border);
}
.sw-billing-invoices-inline__link {
    font-size: var(--sw-text-sm);
    color: var(--sw-brand-text);
    text-decoration: none;
    font-weight: 500;
}

.sw-billing-invoices-inline__link:hover {
    text-decoration: underline;
}

/* Inline invoice table */
.sw-invoice-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--sw-text-base);
}

.sw-invoice-table th {
    padding: 0.6875rem 1rem;
    text-align: left;
    font-size: var(--sw-text-xs);
    font-weight: 600;
    color: var(--sw-text-secondary);
    background: var(--sw-bg-subtle);
    border-bottom: 1px solid var(--sw-border);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.sw-invoice-table td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--sw-border);
    color: var(--sw-text);
}

.sw-invoice-table tr:last-child td {
    border-bottom: none;
}

.sw-invoice-table .sw-invoice-table__right {
    text-align: right;
}

.sw-invoice-table .sw-invoice-table__num {
    font-variant-numeric: tabular-nums;
}

/* Invoice line-item description - subline under the invoice number, works
   for both the recent-invoices widget (.sw-invoice-table) and the full
   invoices list (.sw-table). Kept as a subline (not a separate column) so it
   never widens the table on narrow viewports. */
.sw-invoice-desc {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    font-weight: 400;
    margin-top: 0.125rem;
}

.sw-invoice-desc-more {
    color: var(--sw-text-muted);
}

.sw-invoice-dl-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-secondary);
    text-decoration: none;
    background: var(--sw-bg);
    transition: background 0.15s, color 0.15s;
}

.sw-invoice-dl-btn:hover {
    background: var(--sw-bg-subtle);
    color: var(--sw-text);
}

/* Billing sidebar (right column) */
.sw-billing-sidebar {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-self: start;
}

.sw-billing-sidebar__card {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    overflow: hidden;
}

.sw-billing-plan-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1.25rem;
    background: var(--sw-brand-tint);
    border-bottom: 1px solid rgba(59, 130, 246, 0.15);
}

.sw-billing-plan-name {
    font-size: var(--sw-text-xl);
    font-weight: 700;
    color: var(--sw-brand-text);
    letter-spacing: -0.01em;
}

.sw-billing-plan-body {
    padding: 1.25rem;
}

.sw-billing-plan-meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--sw-border);
    font-size: var(--sw-text-base);
}

.sw-billing-plan-meta-row:last-of-type {
    border-bottom: none;
}

.sw-billing-plan-meta-label {
    color: var(--sw-text-secondary);
}

.sw-billing-plan-meta-value {
    color: var(--sw-text);
    font-weight: 500;
}

.sw-billing-plan-actions {
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--sw-border);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.sw-billing-plan-cancel-text {
    text-align: center;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

.sw-billing-plan-cancel-text a {
    color: var(--sw-text-muted);
    text-decoration: underline;
}

.sw-billing-plan-cancel-text a:hover {
    color: var(--sw-danger-dark);
}

/* Usage bar in sidebar */
.sw-billing-usage-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-billing-usage-track {
    flex: 1;
    height: 4px;
    background: var(--sw-border);
    border-radius: var(--sw-radius-btn);
    overflow: hidden;
}

.sw-billing-usage-fill {
    height: 100%;
    background: var(--sw-brand);
    border-radius: var(--sw-radius-btn);
}

/* Billing address mini-card */
.sw-billing-address-card {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
}

.sw-billing-address-label {
    margin-bottom: 0.25rem;
}

.sw-billing-address-value {
    font-size: var(--sw-text-base);
    color: var(--sw-text);
    line-height: 1.5;
}

.sw-billing-address-edit {
    font-size: var(--sw-text-sm);
    color: var(--sw-brand-text);
    text-decoration: none;
    font-weight: 500;
    white-space: nowrap;
    flex-shrink: 0;
}

.sw-billing-address-edit:hover {
    text-decoration: underline;
}

/* Empty state for invoices inline */
.sw-billing-invoices-empty {
    padding: 2rem 1.25rem;
    text-align: center;
    color: var(--sw-text-muted);
    font-size: var(--sw-text-base);
}

/* Dark mode overrides */
/* .sw-notice needs none: every colour it uses is a theme-aware token (#819). */

html.sw-dark .sw-statement,
html.sw-dark .sw-billing-invoices-inline,
html.sw-dark .sw-billing-sidebar__card {
    box-shadow: var(--sw-shadow-sm);
}

html.sw-dark .sw-line-item--proration {
    background: rgba(245, 158, 11, 0.14);
    border-color: rgba(245, 158, 11, 0.2);
}

html.sw-dark .sw-line-item--proration .sw-line-item__amount {
    color: #fbbf24;
}

html.sw-dark .sw-proration-badge {
    background: rgba(255, 255, 255, 0.06);
    color: var(--sw-text-secondary);
    border-color: rgba(255, 255, 255, 0.1);
}

html.sw-dark .sw-proration-badge--warning {
    color: #fbbf24;
    background: rgba(245, 158, 11, 0.18);
    border-color: rgba(245, 158, 11, 0.28);
}

html.sw-dark .sw-proration-badge--danger {
    background: rgba(239, 68, 68, 0.16);
    color: #fca5a5;
    border-color: rgba(239, 68, 68, 0.28);
}

html.sw-dark .sw-billing-plan-status-badge--warning {
    background: rgba(245, 158, 11, 0.18);
    color: #fbbf24;
    border-color: rgba(245, 158, 11, 0.28);
}

html.sw-dark .sw-statement-total {
    border-color: rgba(59, 130, 246, 0.2);
}

html.sw-dark .sw-billing-plan-top {
    border-color: rgba(59, 130, 246, 0.2);
}

html.sw-dark .sw-invoice-dl-btn {
    background: transparent;
}

html.sw-dark .sw-invoice-dl-btn:hover {
    background: var(--sw-bg-subtle);
}

/* Responsive: stack on narrow screens */
@media (max-width: 767.98px) {
    .sw-billing-ledger-grid {
        grid-template-columns: 1fr;
    }

    .sw-notice {
        flex-direction: column;
        align-items: flex-start;
    }

    .sw-notice > a,
    .sw-notice > form,
    .sw-notice > form .sw-btn,
    .sw-notice .sw-btn {
        width: 100%;
        justify-content: center;
    }

}

/* ── Lead Wait Experience ── */

/* Tile container: three items, only the active one is shown */

/* Dark mode */

/* prefers-reduced-motion: disable fill transition and tile fade */

/* Mobile */

/* ── Updates (FE-15) ── */

.sw-updates-hero {
    min-height: auto;
}

.sw-updates-list {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 720px;
    margin: 0 auto;
}

.sw-updates-card {
    position: relative;
}

.sw-updates-date {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    margin: 0 0 0.375rem;
}

.sw-updates-card-title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 0.5rem;
    letter-spacing: -0.01em;
}

.sw-updates-card-excerpt {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0 0 1.25rem;
}

/* Detail page */
.sw-updates-hero-back {
    margin: 0 0 1.25rem;
}

.sw-updates-back-link {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--sw-text-base);
    color: var(--sw-brand-light);
    text-decoration: none;
}

.sw-updates-back-link:hover {
    color: #fff;
}

.sw-updates-hero-date {
    font-size: var(--sw-text-base);
    color: var(--sw-brand-light);
    margin: 0.5rem 0 0;
}

.sw-updates-post {
    max-width: 680px;
    margin: 0 auto;
}

.sw-updates-post-excerpt {
    font-size: var(--sw-text-xl);
    color: var(--sw-text-secondary);
    margin: 0 0 2rem;
    line-height: 1.7;
}

.sw-updates-section {
    margin-bottom: 2rem;
}

.sw-updates-section-heading {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 0.5rem;
}

.sw-updates-section-body {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    line-height: 1.7;
    margin: 0;
}

/* Unsubscribe page */
.sw-updates-unsubscribe-icon {
    color: var(--sw-success);
}

/* Toggle switch (shared: profile digest, and any inline on/off control) */
.sw-toggle {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    cursor: pointer;
}

.sw-toggle input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}

.sw-toggle-slider {
    position: absolute;
    inset: 0;
    background: var(--sw-border);
    border-radius: var(--sw-radius-btn);
    transition: background 0.2s ease;
    cursor: pointer;
}

.sw-toggle-slider::before {
    content: '';
    position: absolute;
    height: 18px;
    width: 18px;
    left: 3px;
    top: 3px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.2s ease;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    bottom: 3px;
}

.sw-toggle input:checked + .sw-toggle-slider {
    background: var(--sw-brand-strong);
}

.sw-toggle input:checked + .sw-toggle-slider::before {
    transform: translateX(20px);
}

.sw-toggle input:focus-visible + .sw-toggle-slider {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);
}

@media (max-width: 767.98px) {
    .sw-updates-list {
        gap: 1rem;
    }

}

/* ── FE-20: Lead-Funnel Spoiler-Gate lock blocks ── */
.sw-lead-lock-block {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.sw-lead-lock-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.sw-lead-lock-icon {
    width: 18px;
    height: 18px;
    color: var(--sw-text-secondary);
    flex-shrink: 0;
}

.sw-lead-lock-name {
    font-weight: 600;
    font-size: var(--sw-text-md);
    color: var(--sw-text);
}

.sw-lead-lock-badge {
    margin-left: auto;
}
.sw-lead-lock-badge--ok { background: var(--sw-success-tint); color: var(--sw-success-text); }

.sw-lead-lock-copy {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0;
}

/* Dark mode */
html.sw-dark .sw-lead-lock-block {
    background: var(--sw-bg-subtle);
    border-color: var(--sw-border);
}

@media (max-width: 767.98px) {
    .sw-lead-lock-block .sw-btn {
        width: 100%;
        text-align: center;
    }

}

/* ── Next Best Actions Teaser (FE-21) ── */
/* ADR-0005: overlay opacity kept low (0.55/0.5) so the blurred rows' shapes
   and colors stay visible enough to read as "real content, just fuzzy" -
   the original 0.85/0.88 pass nearly matched --sw-bg in dark mode and read
   as an empty/broken card instead. */

.sw-next-actions-teaser {
    position: relative;
    border-radius: var(--sw-radius-inline);
    overflow: hidden;
    /* Tall enough that the CTA never touches the fake rows behind the vignette. */
    min-height: 300px;
}

.sw-next-actions-teaser-rows {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    filter: blur(3px);
    user-select: none;
    pointer-events: none;
}

.sw-next-actions-teaser-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
}

.sw-next-actions-teaser-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--sw-radius-control);
    flex-shrink: 0;
}

.sw-next-actions-teaser-icon svg {
    width: 16px;
    height: 16px;
}

.sw-next-actions-teaser-icon--seo {
    background: var(--sw-brand-tint);
    color: var(--sw-brand-text);
}

.sw-next-actions-teaser-icon--perf {
    background: rgba(234, 179, 8, 0.12);
    color: #b45309;
}

.sw-next-actions-teaser-icon--trust {
    background: rgba(34, 197, 94, 0.12);
    color: var(--sw-success-dark);
}

.sw-next-actions-teaser-label {
    flex: 1;
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text);
}

.sw-next-actions-teaser-pts {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-text-secondary);
    white-space: nowrap;
}


html.sw-dark .sw-next-actions-teaser-row {
    background: var(--sw-bg-subtle);
    border-color: var(--sw-border);
}

html.sw-dark .sw-next-actions-teaser-icon--perf {
    background: rgba(234, 179, 8, 0.16);
    color: #fbbf24;
}

html.sw-dark .sw-next-actions-teaser-icon--trust {
    background: rgba(34, 197, 94, 0.16);
    color: #4ade80;
}

/* ── Competitor Teaser (FE-22) ── */

/* Wrapper: relative-positioned so the lock overlay can cover the blurred charts. */

/* Grid of placeholder metric charts - blurred to hide fake values even in DevTools. */

/* Individual blurred bar value (per bar row, replaces the real numeric value). */

/* Fake bar fills inside the teaser - static widths set via inline style. */

/* Overlay: lock icon + CTA on top of the blurred charts. */

/* Lock icon circle */

/* Remove-list below the teaser - lets users manage tracked competitors. */
.sw-competitor-teaser-remove-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 1rem;
}

.sw-competitor-teaser-remove-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.625rem 1rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
}

.sw-competitor-teaser-remove-name {
    font-size: var(--sw-text-base);
    font-weight: 500;
    color: var(--sw-text);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Empty-state teaser card (0 competitors). */
.sw-competitor-teaser-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 2.5rem 2rem;
    gap: 0.75rem;
}

.sw-competitor-teaser-empty-icon {
    width: 48px;
    height: 48px;
    border-radius: var(--sw-radius-card);
    background: var(--sw-brand-tint);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--sw-brand-text);
    margin-bottom: 0.25rem;
}

.sw-competitor-teaser-empty-icon svg {
    width: 24px;
    height: 24px;
}

.sw-competitor-teaser-empty-title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0;
}

.sw-competitor-teaser-empty-sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
    max-width: 32rem;
}

/* Dark mode */

/* .sw-competitor-teaser-remove-row uses var(--sw-bg-subtle) and var(--sw-border)
   which already resolve to their dark values via the token system - no override needed. */

/* Mobile */

/* ── Competitor Free Partial Benchmark ── */

/* Section A: own-shop score card */
.sw-competitor-own-score {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1rem;
}

.sw-competitor-own-score-eyebrow {
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-muted);
}

.sw-competitor-own-score-body {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

.sw-competitor-own-score-number {
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--sw-text);
}

/* Semantic text color for the score number - no background */
.sw-competitor-own-score-number--good { color: var(--sw-success-text); }
.sw-competitor-own-score-number--moderate { color: var(--sw-warning-text); }
.sw-competitor-own-score-number--poor { color: var(--sw-poor-text); }

.sw-competitor-own-score-meta {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.sw-competitor-own-score-label {
    display: inline-flex;
    align-items: center;
    font-size: var(--sw-text-sm);
    font-weight: 600;
    line-height: 1;
    padding: 0.25rem 0.625rem;
    border-radius: var(--sw-radius-btn);
    color: var(--sw-text-secondary);
    background: transparent;
}

/* Rating pill - tinted bg + semantic text, mirrors sw-dash3-pill-* / analytics subscore pattern */
.sw-competitor-own-score-label--good { background: var(--sw-success-tint); color: var(--sw-success-text); }
.sw-competitor-own-score-label--moderate { background: var(--sw-warning-tint); color: var(--sw-warning-text); }
.sw-competitor-own-score-label--poor { background: var(--sw-poor-tint);    color: var(--sw-poor-text); }

.sw-competitor-own-score-sub {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

/* Section B: honest partial benchmark card */
.sw-competitor-reveal {
    margin-bottom: 1rem;
    padding: 1.5rem;
}

.sw-competitor-reveal-header {
    margin-bottom: 1.25rem;
}

.sw-competitor-reveal-title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
    margin-bottom: 0.25rem;
}

.sw-competitor-reveal-sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

/* Rating colours reuse the existing semantic tokens */

/* Text-color-only modifiers for bar values - no background */
.sw-competitor-reveal-bar-value--good { color: var(--sw-success-text); }
.sw-competitor-reveal-bar-value--moderate { color: var(--sw-warning-text); }
.sw-competitor-reveal-bar-value--poor { color: var(--sw-poor-text); }


/* Plan-limit error flash on the Competitors page - message + upgrade button inline */
.sw-competitor-limit-alert {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* Section C: tracking list heading */
.sw-competitor-teaser-remove-heading {
    margin: 0 0 0.5rem;
}

/* Mobile overrides for the partial benchmark */
@media (max-width: 575.98px) {
    .sw-competitor-own-score-number {
        font-size: var(--sw-text-5xl);
    }

}

/* Reduced-motion: disable bar fill transition */

/* ── Teams ── */

/* Invite card */
.sw-invite-card {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: var(--sw-space-5);
    margin-bottom: var(--sw-space-4);
}

.sw-invite-card__head {
    margin-bottom: var(--sw-space-4);
}

/* Invite row: email + role + submit on one baseline-aligned row (desktop).
   The FE-23 refactor moved the card chrome to .sw-invite-card but dropped the
   row's flex layout, leaving the fields stacked as plain blocks. Restored here.
   Also reused by the agency-profile form so both settings forms match. */
.sw-teams-invite-form {
    width: 100%;
}
.sw-teams-invite-row {
    display: flex;
    align-items: flex-end;
    gap: var(--sw-space-3);
}
.sw-teams-invite-field {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-1);
}
.sw-teams-invite-field--email {
    /* Cap the email field so the invite row reads as a balanced form rather than
       one field stretched across the whole card. */
    flex: 1 1 380px;
    max-width: 460px;
    min-width: 0;
}
.sw-teams-invite-field--role {
    flex: 0 0 auto;
    min-width: 170px;
}
.sw-teams-invite-row .sw-form-label {
    margin-bottom: 0;
}

/* Roles FAQ: a "what do the roles mean?" block at the foot of the Teams page,
   styled as small definition cards rather than a legend inside the invite card. */
.sw-roles-faq {
    margin-top: var(--sw-space-6);
}
.sw-roles-faq__list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--sw-space-4);
    margin: 0;
    padding: 0;
}
.sw-roles-faq__item {
    padding: var(--sw-space-4);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    background: var(--sw-bg);
}
.sw-roles-faq__q {
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 var(--sw-space-1);
}
.sw-roles-faq__a {
    margin: 0;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    line-height: 1.55;
}

/* Shared card heading / sub - used by invite-card and agency-card */
.sw-invite-card__title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 var(--sw-space-1);
}

.sw-invite-card__sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
}

/* Team block (member list + pending list container) */
.sw-team-block {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    overflow: hidden;
    margin-bottom: var(--sw-space-4);
}

/* Shared list reset - member list and pending list */
.sw-member-list,
.sw-pending-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.sw-member-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 1rem;
    padding: 0.875rem 1.25rem;
    transition: background-color 0.15s ease;
}

.sw-member-row:hover {
    background: var(--sw-bg-subtle);
}

.sw-member-row--self {
    background: var(--sw-brand-tint);
}

/* Keep self-tint on hover without !important */
.sw-member-row--self:hover {
    background: var(--sw-brand-tint);
}

.sw-member-row + .sw-member-row {
    border-top: 1px solid var(--sw-border);
}

.sw-member-identity {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

.sw-member-avatar {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px var(--sw-bg), 0 0 0 3.5px var(--sw-border);
}

.sw-member-identity-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.sw-member-name {
    font-size: var(--sw-text-md);
    font-weight: 500;
    color: var(--sw-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sw-team-you {
    font-size: var(--sw-text-xs);
    color: var(--sw-brand-text);
    font-weight: 500;
}

.sw-member-email {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sw-member-role,
.sw-member-action {
    flex-shrink: 0;
}

/* Styled native select */
.sw-select-styled {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='2' stroke='%236b7280' width='16' height='16'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M19.5 8.25l-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.625rem center;
    background-size: 16px;
    padding-right: 2rem;
    cursor: pointer;
}

.sw-select-styled:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
}

/* Smaller select variant in member rows */
.sw-team-role-select.sw-select-styled {
    font-size: var(--sw-text-sm);
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
    padding-left: 0.625rem;
    height: auto;
}

/* Quiet neutral hint: empty state inside the team block, and the owner-managed
   note replacing an action only the account owner may perform (#492). Same
   visual language, different edge treatment - team-empty-hint caps a list
   (border-top only), owner-managed-note is a standalone rounded block since
   it appears in more contexts (shop list banner, billing card, sidebar). */
.sw-team-empty-hint,
.sw-owner-managed-note {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem 1.25rem;
    background: var(--sw-bg-subtle);
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

.sw-team-empty-hint {
    border-top: 1px solid var(--sw-border);
}

.sw-owner-managed-note {
    border-radius: var(--sw-radius-control);
}

.sw-team-empty-hint svg,
.sw-owner-managed-note svg {
    flex-shrink: 0;
    color: var(--sw-text-muted);
}

.sw-pending-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1.25rem;
    flex-wrap: wrap;
}

.sw-pending-row + .sw-pending-row {
    border-top: 1px solid var(--sw-border);
}

.sw-pending-row--expired .sw-pending-email,
.sw-pending-row--expired .sw-pending-meta {
    opacity: 0.6;
}

.sw-pending-email {
    flex: 1;
    min-width: 0;
    font-weight: 500;
    font-size: var(--sw-text-md);
    color: var(--sw-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sw-pending-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}

.sw-pending-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
    margin-left: auto;
}

/* Agency settings card inner layout */

.sw-agency-url-input {
    width: 100%;
}

/* Dark mode */
html.sw-dark .sw-member-avatar {
    box-shadow: 0 0 0 2px var(--sw-bg), 0 0 0 3.5px var(--sw-dark-border);
}

/* Combined: both list-row separators inside sw-team-block use dark border */
html.sw-dark .sw-member-row + .sw-member-row,
html.sw-dark .sw-pending-row + .sw-pending-row {
    border-top-color: var(--sw-dark-border);
}

html.sw-dark .sw-select-styled {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='2' stroke='%238fa3bb' width='16' height='16'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M19.5 8.25l-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");
}

/* Mobile */
@media (max-width: 767.98px) {
    .sw-invite-card {
        padding: var(--sw-space-4);
    }

    .sw-teams-invite-row {
        flex-wrap: wrap;
    }

    .sw-teams-invite-field--email,
    .sw-teams-invite-field--role {
        flex: 1 1 100%;
    }

    .sw-teams-invite-row .sw-btn {
        width: 100%;
    }

    /* Two-column grid: identity spans both columns (row 1), role+action sit side-by-side (row 2) */
    .sw-member-row {
        grid-template-columns: 1fr auto;
        gap: 0.5rem;
        padding: 0.75rem 1rem;
    }

    .sw-member-identity {
        grid-column: 1 / -1;
    }

    .sw-pending-row {
        gap: 0.5rem;
    }

    .sw-pending-email {
        flex: 1 1 100%;
    }

    .sw-pending-actions {
        margin-left: 0;
        margin-top: 0.125rem;
    }

}

/* ── Lead Results: live-scan panel (sw-result-panel-*) ── */

/*
 * The panel always renders on a dark charcoal background (--sw-footer-bg),
 * regardless of the page theme. Local tokens scoped to .sw-result-panel
 * ensure text colors are always correct for that dark surface.
 */
.sw-result-panel {
    /* Always-dark surface local tokens */

    max-width: 560px;
    margin: 0 auto 2rem;
    background: var(--sw-footer-bg);
    border: 1px solid rgba(143, 163, 187, 0.14);
    border-radius: var(--sw-radius-card);
    overflow: hidden;
    box-shadow: var(--sw-shadow-lg);
}

/* Browser chrome bar */
.sw-result-panel__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid rgba(143, 163, 187, 0.10);
}

.sw-result-panel__urlbar {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    background: rgba(143, 163, 187, 0.08);
    border: 1px solid rgba(143, 163, 187, 0.12);
    border-radius: var(--sw-radius-sm);
    padding: 4px 10px;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sw-result-panel__lock-icon {
    width: 12px;
    height: 12px;
    flex-shrink: 0;
}

.sw-result-panel__urlbar-sub {
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-xs);
}

.sw-result-panel__urlbar b {
    color: var(--sw-text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Panel body */
.sw-result-panel__body {
    padding: 16px;
}

/* Category check rows */
.sw-result-panel__checks {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.sw-result-panel__check {
    display: flex;
    align-items: center;
    gap: 12px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(143, 163, 187, 0.12);
    border-radius: var(--sw-radius-inline);
    padding: 11px 13px;
    transition: border-color 0.3s ease;
}

.sw-result-panel__check--ok {
    border-color: rgba(34, 197, 94, 0.28);
}

.sw-result-panel__check--warn {
    border-color: rgba(251, 113, 133, 0.28);
}

.sw-result-panel__check-ic {
    width: 30px;
    height: 30px;
    border-radius: var(--sw-radius-inline);
    flex-shrink: 0;
    display: grid;
    place-items: center;
    background: var(--sw-brand-tint);
    color: var(--sw-brand-light);
}

html.sw-dark .sw-result-panel__check-ic {
    background: rgba(59, 130, 246, 0.14);
}

.sw-result-panel__check-ic svg {
    width: 15px;
    height: 15px;
}

.sw-result-panel__check-meta {
    flex: 1;
    min-width: 0;
}

.sw-result-panel__check-name {
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
    display: flex;
    align-items: center;
    gap: 7px;
}

.sw-result-panel__cnt {
    font-size: var(--sw-text-2xs);
    font-weight: 600;
    color: var(--sw-text-secondary);
    background: rgba(143, 163, 187, 0.10);
    border: 1px solid rgba(143, 163, 187, 0.18);
    border-radius: var(--sw-radius-btn);
    padding: 1px 7px;
    line-height: 1.5;
    white-space: nowrap;
}

/* Skeleton placeholder for cnt badge while loading */
.sw-skeleton--cnt {
    display: inline-block;
    width: 48px;
    height: 16px;
    border-radius: var(--sw-radius-btn);
    background: rgba(143, 163, 187, 0.14);
    animation: sw-skeleton-pulse 1.5s ease-in-out infinite;
    vertical-align: middle;
    border: none;
    padding: 0;
}

.sw-result-panel__cnt--ok {
    color: var(--sw-success-text);
    border-color: rgba(34, 197, 94, 0.30);
    background: rgba(34, 197, 94, 0.10);
}

.sw-result-panel__cnt--warn {
    color: var(--sw-poor-text);
    border-color: rgba(251, 113, 133, 0.28);
    background: rgba(251, 113, 133, 0.08);
}

.sw-result-panel__check-desc {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-secondary);
    margin-top: 2px;
}

/* Status area (right side of each check row) */
.sw-result-panel__status {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 5px;
}

.sw-result-panel__spinner {
    display: block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid rgba(143, 163, 187, 0.3);
    border-top-color: var(--sw-brand-light);
    animation: sw-result-panel-spin 0.7s linear infinite;
}

@keyframes sw-result-panel-spin {
    to { transform: rotate(360deg); }
}

.sw-result-panel__sdot {
    display: block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.sw-result-panel__sdot--ok {
    background: var(--sw-success-text);
    box-shadow: 0 0 6px rgba(34, 197, 94, 0.5);
}

.sw-result-panel__sdot--warn {
    background: var(--sw-poor-text);
    box-shadow: 0 0 6px rgba(251, 113, 133, 0.4);
}

/* Score line */
/* #837: the quotability sentence under the Agentic row. Quiet, one line, and it
   only exists once the measurement is in. */
.sw-result-panel__answerable { margin: 8px 2px 0; font-size: var(--sw-text-sm); line-height: 1.45; color: var(--sw-text-secondary, #9aa8bd); }
.sw-result-panel__answerable--ok { color: var(--sw-success-text, #4ade80); }

.sw-result-panel__scoreline {
    /* Sits above the category rows since #835, so the gap belongs below it. */
    margin-bottom: 14px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(143, 163, 187, 0.12);
    border-radius: var(--sw-radius-inline);
    padding: 13px 15px;
}

.sw-result-panel__sl-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}

.sw-result-panel__sl-lbl {
    font-size: var(--sw-text-xs);
    color: var(--sw-text-secondary);
    font-weight: 500;
}

.sw-result-panel__sl-val {
    font-weight: 600;
    font-size: var(--sw-text-base);
}

.sw-result-panel__sl-num {
    font-size: var(--sw-text-3xl);
    color: var(--sw-text);
    font-weight: 700;
}

.sw-result-panel__sl-denom {
    color: var(--sw-text-secondary);
}

.sw-result-panel__track {
    height: 7px;
    border-radius: var(--sw-radius-btn);
    background: rgba(143, 163, 187, 0.12);
    overflow: hidden;
}

.sw-result-panel__verdict {
    margin: 0.75rem 0 0;
    font-size: var(--sw-text-base);
    line-height: 1.55;
    color: var(--sw-text-secondary);
}

.sw-result-panel__track-fill {
    display: block;
    height: 100%;
    width: 0%;
    border-radius: var(--sw-radius-btn);
    background: linear-gradient(90deg, var(--sw-poor-text) 0%, var(--sw-warning) 50%, var(--sw-success-text) 100%);
}

/* Mobile */
@media (max-width: 767.98px) {
    .sw-result-panel {
        margin-left: 0;
        margin-right: 0;
        border-radius: var(--sw-radius-card);
    }

    .sw-result-panel__urlbar {
        font-size: var(--sw-text-2xs);
    }

}

/* ── Analytics: scan-panel header wrap ── */

/* ── Analytics Command Centre (Version C) ──────────────────────────────────
   sw-cmd-* classes for the dense "command center" overview on /account/analytics.
   Uses --sw-* tokens throughout; never raw hex. Dark-mode aware via the same
   html.sw-dark overrides as the rest of the design system.
   ─────────────────────────────────────────────────────────────────────────── */

/* Outer shell */
.sw-cmd {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-4);
    margin-bottom: var(--sw-space-5);
}

/* ── Row 1: score panel + trend chart ── */
.sw-cmd-top {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: var(--sw-space-4);
}

/* Glass score panel */
.sw-cmd-score-panel {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 1.375rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}
html.sw-dark .sw-cmd-score-panel {
    background: linear-gradient(160deg, rgba(30,37,53,.7), rgba(16,19,28,.85));
    border-color: rgba(255,255,255,.13);
}
.sw-cmd-score-num {
    font-size: 3rem; /* #654: display cap */
    font-weight: 800;
    line-height: .9;
    letter-spacing: -.03em;
    color: var(--sw-text);
    font-variant-numeric: tabular-nums;
}
.sw-cmd-score-num span {
    font-size: var(--sw-text-3xl);
    color: var(--sw-text-muted);
    font-weight: 600;
    letter-spacing: 0;
}
.sw-cmd-score-num--empty {
    color: var(--sw-text-muted);
}
.sw-cmd-score-empty {
    font-size: var(--sw-text-base);
    color: var(--sw-text-muted);
}

/* Rating chip */

/* Score footer stats */
.sw-cmd-score-foot {
    display: flex;
    gap: 1.125rem;
    margin-top: auto;
    padding-top: .875rem;
    flex-wrap: wrap;
}
.sw-cmd-score-stat { font-size: var(--sw-text-xs); color: var(--sw-text-secondary); }
.sw-cmd-score-stat__label { display: block; margin-bottom: .1rem; }
.sw-cmd-score-stat__value { display: block; font-size: var(--sw-text-base); color: var(--sw-text); font-variant-numeric: tabular-nums; }
.sw-cmd-score-stat__value--up { color: var(--sw-success-text); }
.sw-cmd-score-stat__value--down { color: var(--sw-poor-text); }

/* Trend panel */
.sw-cmd-trend-panel {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 1.125rem 1.25rem .875rem;
    display: flex;
    flex-direction: column;
}
.sw-cmd-trend-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .375rem;
}
.sw-cmd-trend-title {
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
}
.sw-cmd-trend-chart {
    flex: 1;
    min-height: 220px;
}
.sw-cmd-trend-legend {
    margin-top: .5rem;
    margin-bottom: 0;
}
.sw-cmd-trend-upsell {
    flex: 1;
}

/* Score-history stock chart wrapper (Issue #532) - range toggle, chart box,
   plan-retention/empty notes and the trend summary caption all stack inside
   one data-controller="metric-chart" element (_score_trend_chart.html.twig);
   the gap keeps them from touching the way plain block margins alone would
   not (mirrors .sw-widget's flex-column + gap on the old dashboard trend
   widget the toggle/active-state classes below are shared with). Named
   sw-score-history-chart, NOT sw-score-trend - that name is already the
   small inline delta indicator (_trend.html.twig, see "Score trend" in the
   component library), an unrelated component this would have collided with. */
.sw-score-history-chart {
    display: flex;
    flex-direction: column;
    gap: var(--sw-space-3);
}

/* Keep the default align-items:stretch for the chart box/notes/summary
   (they need the full width) but not for the toggle pill, which must stay
   content-sized and left-aligned instead of stretching edge to edge. */
.sw-score-history-chart > .sw-trend-toggle {
    align-self: flex-start;
}

/* The short trend sparkline: inline SVG, no Chart.js instance, no JS at all.
   It draws REAL scores since the gating pattern of 2026-09-04 - the class used
   to be called fake-trend for a reason that no longer exists. Colours track the
   design-system tokens so it stays correct in dark mode without a re-render. */
.sw-trend-sparkline {
    width: 100%;
    height: 100%;
    display: block;
}
.sw-trend-sparkline__area {
    fill: var(--sw-brand);
    fill-opacity: 0.12;
}
.sw-trend-sparkline__line {
    fill: none;
    stroke: var(--sw-text-secondary);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ── Row 2: Uptime strip ── */
.sw-cmd-uptime {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: .875rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    position: relative;
}
.sw-cmd-uptime__meta {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-shrink: 0;
}
.sw-cmd-uptime__pct {
    font-size: var(--sw-text-md);
    font-weight: 700;
    color: var(--sw-text);
    font-variant-numeric: tabular-nums;
}
.sw-cmd-uptime__track {
    flex: 1;
    display: flex;
    gap: 2px;
    height: 28px;
    align-items: stretch;
    position: relative;
    min-width: 0;
}
.sw-cmd-uptime__bar {
    flex: 1;
    border-radius: var(--sw-radius-xs);
    display: block;
    font-style: normal;
    transition: opacity .1s;
    cursor: default;
}
.sw-cmd-uptime__bar:hover { opacity: .75; }
.sw-cmd-uptime__bar--ok { background: var(--sw-success); }
.sw-cmd-uptime__bar--minor { background: var(--sw-warning); }
.sw-cmd-uptime__bar--major { background: var(--sw-danger); }
.sw-cmd-uptime__bar--no_data { background: var(--sw-border); }
.sw-cmd-uptime__link {
    font-size: var(--sw-text-xs);
    font-weight: 500;
    color: var(--sw-brand-text);
    text-decoration: none;
    flex-shrink: 0;
    white-space: nowrap;
}
.sw-cmd-uptime__link:hover { text-decoration: underline; }

/* ── Row 3: KPI sparkline cards ── */

/* ── Row 4: All-metrics table ── */
/* Category colour dots - shared between category headers and legacy dot cells */
.sw-cmd-dot {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    flex-shrink: 0;
    display: inline-block;
}
.sw-cmd-dot--perf { background: var(--sw-brand); }
.sw-cmd-dot--seo { background: var(--sw-success); }
.sw-cmd-dot--trust { background: var(--sw-warning); }
.sw-cmd-dot--a11y { background: var(--sw-brand-light); }
.sw-cmd-dot--social { background: var(--sw-text-muted); }
.sw-cmd-dot--security { background: var(--sw-brand-light); }

/* Trend sparkline */

/* Status chip - used in both category headers and metric rows */

/* ── Per-category metric sections ── */
.sw-cmd-cat-header {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .875rem 1.25rem;
    border-bottom: 1px solid var(--sw-border);
    background: var(--sw-bg-subtle);
}
.sw-cmd-cat-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--sw-text-secondary);
}
.sw-cmd-cat-title {
    /* Section heading: visibly a level above the 14px metric rows, and the
       same size as the top-bar tabs it mirrors (icon + title). */
    font-size: var(--sw-text-xl);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--sw-text);
    margin: 0;
    flex: 1;
}

/* Metric row: full-width clickable link */
.sw-cmd-mrow {
    display: grid;
    /* name | value (fixed) | sparkline | status badge (fixed) | chevron */
    grid-template-columns: 1fr 7.5rem 2.5rem 6.75rem 16px;
    align-items: center;
    gap: .75rem;
    padding: .75rem 1.25rem;
    border-top: 1px solid var(--sw-border);
    text-decoration: none;
    color: var(--sw-text);
    transition: background .1s;
}
.sw-cmd-mrow:first-child { border-top: none; }
.sw-cmd-mrow:hover { background: rgba(59,130,246,.03); }
html.sw-dark .sw-cmd-mrow:hover { background: rgba(255,255,255,.06); }
.sw-cmd-mrow__name {
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sw-cmd-mrow__val {
    font-variant-numeric: tabular-nums; /* #654: no mono in product chrome */
    font-size: var(--sw-text-base);
    font-weight: 600;
    white-space: nowrap;
    text-align: right;
}
.sw-cmd-mrow__val small { color: var(--sw-text-muted); font-weight: 400; }
.sw-cmd-mrow__empty { color: var(--sw-text-muted); }
/* Status badge column - fixed width so every badge left/right edge aligns */
.sw-cmd-mrow__chevron {
    width: 16px;
    height: 16px;
    color: var(--sw-text-muted);
    flex-shrink: 0;
}
.sw-cmd-mrow:hover .sw-cmd-mrow__chevron { color: var(--sw-brand-text); }

/* ── Competitor compare row - sw-cmd-mrow modifier used by Competitors instead
   of a fixed value+sparkline, showing the own value plus EVERY tracked
   competitor's value at once. Height is allowed to grow with the competitor
   count (unlike the fixed-height cmd_metric_row). ── */
.sw-cmd-mrow--compare {
    grid-template-columns: 1fr 6rem 1fr 16px;
    align-items: flex-start;
    padding-top: .875rem;
    padding-bottom: .875rem;
}
.sw-cmd-mrow--compare .sw-cmd-mrow__name,
.sw-cmd-mrow--compare .sw-cmd-mrow__val,
.sw-cmd-mrow--compare .sw-cmd-mrow__chevron {
    padding-top: .1rem;
}
.sw-cmd-mrow__val--own { text-align: left; }
.sw-cmd-mrow__compare-list {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .375rem 1rem;
    min-width: 0;
}
.sw-cmd-mrow__compare-item {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    font-size: var(--sw-text-sm);
    max-width: 11rem;
}
.sw-cmd-mrow__compare-name {
    color: var(--sw-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 7rem;
}
.sw-cmd-mrow__compare-val {
    font-variant-numeric: tabular-nums; /* #654: no mono in product chrome */
    font-weight: 600;
    color: var(--sw-text);
    white-space: nowrap;
}
/* Trend marker - stated from the OWN shop's perspective (see
   CompetitorController::marker()): "ahead" = the competitor beats you,
   "behind" = you beat the competitor. Colours mirror the long-standing
   sw-competitor-marker convention (ahead = brand, behind = success, never a
   danger red - being beaten by a competitor isn't styled as an error). */
.sw-cmd-trend {
    font-size: var(--sw-text-xs);
    font-weight: 700;
    line-height: 1;
}
.sw-cmd-trend--ahead { color: var(--sw-brand-text); }
.sw-cmd-trend--behind { color: var(--sw-success-text); }
.sw-cmd-trend--equal { color: var(--sw-text-muted); }

@media (max-width: 767.98px) {
    /* Explicit row/column placement (not auto-flow) so the chevron reliably
       stays on row 1 next to name+value, with the compare list wrapping to
       its own full-width row 2. */
    .sw-cmd-mrow--compare {
        grid-template-columns: 1fr auto 16px;
        grid-template-rows: auto auto;
    }
    .sw-cmd-mrow--compare .sw-cmd-mrow__name { grid-column: 1; grid-row: 1; }
    .sw-cmd-mrow--compare .sw-cmd-mrow__val--own { grid-column: 2; grid-row: 1; }
    .sw-cmd-mrow--compare .sw-cmd-mrow__chevron { grid-column: 3; grid-row: 1; }
    .sw-cmd-mrow--compare .sw-cmd-mrow__compare-list {
        grid-column: 1 / -1;
        grid-row: 2;
        margin-top: .375rem;
    }

}

/* ── Responsive ── */
@media (max-width: 1040px) {
    .sw-cmd-top { grid-template-columns: 1fr; }

}
@media (max-width: 767.98px) {
    .sw-cmd-uptime { flex-direction: column; align-items: flex-start; }
    .sw-cmd-uptime__track { width: 100%; }
    .sw-cmd-score-num { font-size: 3rem; }
    /* On mobile: drop sparkline column, shrink value/stat to auto */
    .sw-cmd-mrow { grid-template-columns: 1fr auto 6.75rem 16px; }
    /* Allow check names to wrap to a second line instead of ellipsis-truncating
       (e.g. "Performance Score" → "Performance Sc…" at 390px) */
    .sw-cmd-mrow__name {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        line-height: 1.25;
    }

}

/* ── Dashboard reskin: dark-tech command-center ────────────────────────────
   Overrides / extensions for sw-dash3-* to match the analytics command-center
   and uptime page aesthetic. Uses --sw-* tokens only; never raw hex.
   New layout classes: sw-dash3-hero, sw-dash3-overview, sw-dash3-stats-row.
   ─────────────────────────────────────────────────────────────────────────── */

/* Head: eyebrow + h1 cadence matching sw-uptime-eyebrow */

/* Restyle dense list table to match sw-cmd-table */
.sw-dash3-listwrap {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    overflow-x: auto;
}
html.sw-dark .sw-dash3-listwrap {
    background: linear-gradient(160deg, rgba(30,37,53,.6), rgba(16,19,28,.75));
    border-color: rgba(255,255,255,.10);
}
.sw-dash3-table thead th {
    background: transparent;
    text-align: left;
    font-size: var(--sw-text-2xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--sw-text-muted);
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--sw-border);
}
.sw-dash3-table tbody tr:hover {
    background: rgba(59,130,246,.03);
}
html.sw-dark .sw-dash3-table tbody tr:hover {
    background: rgba(255,255,255,.06);
}

/* Toolbar: section title uses command-center uppercase eyebrow style */
.sw-dash3-toolbar .sw-section-title {
    font-size: var(--sw-text-2xs);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--sw-text-muted);
    margin: 0;
}

/* Filter chip pills: match sw-cmd-kpi hover ring */
.sw-dash3-chip {
    background: var(--sw-bg-subtle);
    padding: .375rem .75rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn);
    color: var(--sw-text-secondary);
    font-family: inherit;
    font-weight: 500;
    font-size: var(--sw-text-sm);
    cursor: pointer;
    transition: .15s ease;
}
.sw-dash3-chip.is-active {
    background: var(--sw-brand-tint);
    border-color: rgba(59,130,246,.3);
    color: var(--sw-brand-text);
}

html.sw-dark .sw-dash3-listwrap {
    border-color: rgba(255,255,255,.10);
}

/* Responsive: hero collapses to single column below 900 px */
@media (max-width: 767.98px) {
    .sw-section-title {
        font-size: var(--sw-text-2xs);
    }

}

/* ── Scan timeout notice ── */
.sw-poll-timeout {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 1.25rem 1.5rem;
    margin: 1.5rem 0;
}
.sw-poll-timeout__icon {
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--sw-brand-tint);
    border-radius: var(--sw-radius-control);
    color: var(--sw-brand-text);
}
.sw-poll-timeout__icon svg {
    width: 1.25rem;
    height: 1.25rem;
}
.sw-poll-timeout__body {
    flex: 1;
}
.sw-poll-timeout__title {
    font-size: var(--sw-text-md);
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 .25rem;
}
.sw-poll-timeout__sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
}
.sw-poll-timeout__actions {
    flex-shrink: 0;
    align-self: center;
}
@media (max-width: 767.98px) {
    .sw-poll-timeout {
        flex-direction: column;
    }
    .sw-poll-timeout__actions {
        align-self: flex-start;
    }

}

/* ── Welcome Modal ── */

/* h2 heading inside the dialog (mirrors the .sw-modal h3 rule for h2). */
.sw-modal h2.sw-modal-title {
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--sw-text);
    margin: 0;
}

/* Body text block - adds bottom spacing between paragraphs. */
.sw-modal-body {
    margin-top: 1rem;
    margin-bottom: 1.25rem;
}

.sw-modal-body p {
    /* Override the generic .sw-modal p bottom margin so the last child is
       flush against .sw-modal-actions without double-spacing. */
    margin-bottom: 0.75rem;
}

.sw-modal-body p:last-child {
    margin-bottom: 0;
}

/* Lighter secondary paragraph within the modal body. */

/* ── Shop Roster (mirrors .sw-statement from billing) ── */

/* Contained roster card - parallels the billing statement block */
/* Merged Workspaces & Shops (#592): per-workspace section header (name + meta +
   workspace actions) above each roster, and a per-workspace add-shop footer row. */
.sw-ws-section-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sw-space-3);
    margin: var(--sw-space-5) 0 var(--sw-space-2);
}
.sw-ws-section-head__main {
    min-width: 0;
}
.sw-ws-section-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.25rem 0 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}
.sw-ws-section-meta__sep {
    color: var(--sw-border);
}
.sw-ws-meta-form {
    display: inline;
    margin: 0;
}
.sw-linkbtn {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--sw-brand-text);
    cursor: pointer;
}
.sw-linkbtn:hover {
    text-decoration: underline;
}
.sw-ws-section-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
    align-items: center;
}
.sw-shop-add-row {
    margin: 0;
    border-top: 1px dashed var(--sw-border);
}
.sw-shop-add-row__btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    background: none;
    border: 0;
    padding: 0.75rem 1.25rem;
    font: inherit;
    font-weight: 600;
    font-size: var(--sw-text-sm);
    color: var(--sw-brand-text);
    cursor: pointer;
}
.sw-shop-add-row__btn:hover {
    background: var(--sw-bg-subtle);
}
@media (max-width: 767.98px) {
    .sw-ws-section-head {
        flex-direction: column;
    }
    .sw-ws-section-actions {
        width: 100%;
    }

}

.sw-shop-roster {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    overflow: hidden;
    margin-bottom: 1.5rem;
}

/* Roster header - parallels .sw-statement__header */
.sw-shop-roster__header {
    padding: 0.875rem 1.25rem;
    background: var(--sw-bg-subtle);
    border-bottom: 1px solid var(--sw-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
/* Shop row - line-item inside the roster, not an independent card */
.sw-shop-roster .sw-shop-item {
    display: grid;
    grid-template-columns: 36px 1fr auto auto;
    align-items: center;
    gap: 0 1rem;
    padding: var(--sw-card-pad-sm);
    border-bottom: 1px solid var(--sw-border);
    border-radius: 0;
    box-shadow: none;
    background: var(--sw-bg);
    transition: background 0.15s ease;
}

.sw-shop-roster .sw-shop-item:last-child {
    border-bottom: none;
}

.sw-shop-roster .sw-shop-item:hover {
    background: var(--sw-bg-subtle);
    transform: none;
}

/* Score column - mirrors .sw-line-item__amount in billing */

/* Mobile: stack score + actions below the info column */
@media (max-width: 767.98px) {
    .sw-shop-roster .sw-shop-item {
        grid-template-columns: 36px 1fr;
        grid-template-rows: auto auto;
    }

    .sw-shop-item-actions {
        grid-column: 2;
    }

}

/* Dark mode - all tokens already have dark overrides; no extra rules needed */

/* ── Competitor benchmark - stacked layout ── */

.sw-competitor-stacked-blocks {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* One block per metric */
.sw-competitor-stacked-block {
    border-top: 2px solid var(--sw-border);
    padding-top: 1rem;
}

/* Headline (ShopWatch Score) block uses brand accent on top border */
.sw-competitor-stacked-block--headline {
    border-top-color: var(--sw-brand);
}

/* Label row: metric name + Pro badge side by side */
.sw-competitor-stacked-label-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
/* One row: domain + bar + value */
.sw-competitor-stacked-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Gap between own row and competitor row within one block */
.sw-competitor-stacked-row + .sw-competitor-stacked-row {
    margin-top: 0.375rem;
}

/* Competitor row on Free: only the bar + value are blurred + inert - the
   competitor domain name is a fact the user entered themselves (also shown
   unblurred in the tracking list below), not a real analysis result, so it
   stays sharp and readable (ADR-0005 clarification). */
.sw-competitor-stacked-row--locked .sw-competitor-stacked-bar-track,
.sw-competitor-stacked-row--locked .sw-competitor-stacked-value {
    filter: blur(4px);
    user-select: none;
    pointer-events: none;
}

/* Domain label column */
.sw-competitor-stacked-domain {
    flex: 0 0 9rem;
    font-size: var(--sw-text-sm);
    color: var(--sw-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Bar track */
.sw-competitor-stacked-bar-track {
    flex: 1;
    height: 10px;
    border-radius: var(--sw-radius-sm);
    background: var(--sw-border);
    overflow: hidden;
}

/* Bar fill - reuses sw-rating-* fill colours */
.sw-competitor-stacked-bar-fill {
    display: block;
    height: 100%;
    border-radius: var(--sw-radius-sm);
    transition: width 0.4s ease-out;
    background: var(--sw-text-muted);
}

.sw-competitor-stacked-bar-fill.sw-rating-good { background: var(--sw-success); }
.sw-competitor-stacked-bar-fill.sw-rating-moderate { background: var(--sw-warning); }
.sw-competitor-stacked-bar-fill.sw-rating-poor { background: var(--sw-danger); }

/* Numeric value column */
.sw-competitor-stacked-value {
    flex: 0 0 2.5rem;
    text-align: right;
    font-size: var(--sw-text-base);
    font-weight: 700;
    color: var(--sw-text-muted);
    white-space: nowrap;
}

/* Responsive: mobile */
@media (max-width: 575.98px) {
    .sw-competitor-stacked-domain {
        flex: 0 0 6rem;
    }

    .sw-competitor-stacked-value {
        flex: 0 0 2rem;
        font-size: var(--sw-text-sm);
    }

}

/* Reduced-motion: disable bar fill transition */
@media (prefers-reduced-motion: reduce) {
    .sw-competitor-stacked-bar-fill { transition: none; }

}

/* ── Techstack (v2) ── */

/* Stat strip */
/* #849: die Kachel-Anatomie ist weg, der Haken bleibt - siehe .sw-figures. */
.sw-ts-stat-strip { margin-bottom: 2rem; }

/* Category list container */
/* Two columns on wide screens (2026-09-29): most categories hold one
   technology, and eleven full-width single-row cards made a long, thin page. */
.sw-ts-categories { display: flex; flex-direction: column; gap: 1.25rem; }
@media (min-width: 1100px) {
    .sw-ts-categories { display: block; column-count: 2; column-gap: 1.25rem; }
    .sw-ts-categories > .sw-ts-category { break-inside: avoid; margin-bottom: 1.25rem; }
}
.sw-ts-intro { margin: 0 0 1.5rem; max-width: 72ch; color: var(--sw-text-secondary); font-size: var(--sw-text-base); }

/* Single category block */
.sw-ts-category {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    overflow: hidden;
}

/* Category header */
.sw-ts-cat-header {
    display: flex; align-items: center; gap: 10px;
    padding: 0.75rem 1rem;
    background: var(--sw-bg-subtle);
    border-bottom: 1px solid var(--sw-border);
}
.sw-ts-cat-dot {
    width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
    background: var(--sw-brand);
}
.sw-ts-cat-name {
    font-size: var(--sw-text-base); font-weight: 600; color: var(--sw-text);
}
.sw-ts-cat-count {
    font-size: var(--sw-text-xs); color: var(--sw-text-muted);
    margin-left: auto;
}

/* Context line linking a category to the score it affects */
.sw-ts-cat-context {
    font-size: var(--sw-text-sm); color: var(--sw-text-secondary);
    padding: 0.625rem 1rem 0;
    margin: 0;
}
.sw-ts-cat-context a { color: var(--sw-brand-text); font-weight: 500; }
.sw-ts-cat-context a:hover { text-decoration: underline; }

/* Tech list */
.sw-ts-list {
    list-style: none; margin: 0; padding: 0;
}
.sw-ts-row {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 1rem;
    border-bottom: 1px solid var(--sw-border);
    background: var(--sw-bg);
    transition: background 0.15s;
}
.sw-ts-row:last-child { border-bottom: none; }
.sw-ts-row:hover { background: var(--sw-bg-subtle); }

/* Icon tile (#957 S-3 family): one square for a technology, a shop or a
   competitor - its own icon, or an initial when there is none. Shared by
   techstack rows, the shop list and the competitor suggestions, so all three
   read as one design language (founder review 2026-09-28). */
.sw-icon-tile {
    width: 36px; height: 36px; flex-shrink: 0;
    border-radius: var(--sw-radius-control);
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    display: inline-flex; align-items: center; justify-content: center;
    overflow: hidden;
}
.sw-icon-tile--sm { width: 32px; height: 32px; }
.sw-icon-tile--img { background: var(--sw-icon-tile-img-bg); border-color: transparent; }
.sw-icon-tile img { max-width: 20px; max-height: 20px; object-fit: contain; }
.sw-icon-tile svg { width: 16px; height: 16px; color: var(--sw-text-muted); }
.sw-icon-tile__letter { font-size: var(--sw-text-base); font-weight: 700; color: var(--sw-brand-text); line-height: 1; }

.sw-ts-row-body { flex: 1; min-width: 0; }
.sw-ts-row-name {
    font-size: var(--sw-text-base); font-weight: 500; color: var(--sw-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    display: block; text-decoration: none;
}
a.sw-ts-row-name:hover { color: var(--sw-brand-text); text-decoration: underline; }
.sw-ts-version { white-space: nowrap; flex-shrink: 0; }

@media (max-width: 767.98px) {
    .sw-ts-stat-strip { flex-direction: column; }
    .sw-ts-stat { border-right: none; border-bottom: 1px solid var(--sw-border); }
    .sw-ts-stat:last-child { border-bottom: none; }

}

@media (prefers-reduced-motion: reduce) {
    .sw-ts-row { transition: none; }

}

/* ── Analytics Detail ── */


.sw-md-description { margin-bottom: 1.5rem; }

.sw-md-accordion {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.sw-md-accordion-item {
    background: var(--sw-bg-subtle);
    border-radius: var(--sw-radius-control);
    border: 1px solid var(--sw-border);
}

.sw-md-accordion-summary {
    padding: 0.75rem 0.875rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    color: var(--sw-text);
}

.sw-md-accordion-summary::-webkit-details-marker { display: none; }

.sw-md-accordion-chevron {
    width: 16px;
    height: 16px;
    color: var(--sw-text-muted);
    flex-shrink: 0;
    margin-left: auto;
    transition: transform 0.2s ease;
}

details[open] .sw-md-accordion-chevron {
    transform: rotate(90deg);
}

.sw-md-accordion-body {
    padding: 0 0.875rem 0.75rem 2.25rem;
}

@media (prefers-reduced-motion: reduce) {
    .sw-md-accordion-chevron { transition: none; }

}

/* ── Pending-upgrade banner (checkout-first hold) ── */
.sw-billing-pending-upgrade__decline { margin: 0; }
.sw-btn-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--sw-brand-text);
    font: inherit;
    font-weight: 500;
    text-decoration: underline;
    cursor: pointer;
}
.sw-btn-link:hover { text-decoration: none; }

/* ── Checkout modal (registration step 3) ── */
.sw-checkout-modal { max-width: 520px; width: 100%; }
.sw-checkout-summary {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.875rem 1rem;
    margin: 0 0 1rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-inline);
    background: var(--sw-brand-tint);
}
.sw-checkout-summary strong { font-size: var(--sw-text-xl); }
.sw-checkout-section-title {
    font-size: var(--sw-text-sm);
    font-weight: 600;
    color: var(--sw-text-secondary);
    margin: 1rem 0 0.5rem;
}
.sw-checkout-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}
.sw-checkout-grid--full { grid-column: 1 / -1; }
.sw-checkout-submit { width: 100%; margin-top: 1rem; }
.sw-checkout-decline { text-align: center; margin-top: 0.75rem; }

.sw-home-scan-form {
    max-width: 480px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: var(--sw-radius-panel);
    padding: 1.25rem;
}

.sw-home-scan-form .sw-form-label {
    color: rgba(255, 255, 255, 0.85);
}

.sw-home-scan-row {
    display: flex;
    gap: 0.625rem;
    /* Top-align so the button keeps its height when the status line fills below the input */
    align-items: flex-start;
}

.sw-home-scan-row .sw-url-input-wrapper {
    flex: 1;
    min-width: 14rem; /* #953 P-01: a long button never squeezes the field to a slit */
}

.sw-home-scan-row .sw-btn {
    flex-shrink: 0;
    white-space: nowrap;
}

/* Reserve the validation-status line so validating never shifts the form (no jump) */
.sw-home-scan-form .sw-url-status {
    min-height: 1.25rem;
    margin-top: 0.5rem;
}

.sw-home-scan-form .sw-url-status:empty {
    margin-top: 0.5rem;
}

.sw-home-hero-hint {
    font-size: var(--sw-text-base);
    color: rgba(255, 255, 255, 0.6);
    margin: 0.875rem 0 0;
}

@media (max-width: 575.98px) {
    /* #912: stretch, and let the button text wrap. The base row top-aligns its
       items and keeps the button on one line - fine side by side, but stacked
       it left the field at its content width (207 px next to a 324 px button)
       and pushed the /agentic card to 474 px on a 390 px screen, clipped on
       both sides by the hero. */
    .sw-home-scan-row {
        flex-direction: column;
        align-items: stretch;
    }

    .sw-home-scan-row .sw-url-input-wrapper {
        width: 100%;
    }

    .sw-home-scan-row .sw-btn {
        width: 100%;
        justify-content: center;
        white-space: normal;
        text-align: center;
    } /* #953 P-15 */

}

@keyframes sw-home-live {
    0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.45); }
    70% { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
    100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}

@keyframes sw-uptime-grow {
    from { transform: scaleY(0); transform-origin: bottom; opacity: 0; }
    to   { transform: scaleY(1); opacity: 1; }
}

/* ── /try step-reveal ── */

/* Scan caption cycling on a category row's description while pending
   (see lead_results_controller.js `_cycleScanline`). */
.sw-result-panel__check-desc[data-scan-labels] {
    min-height: 1em;
    transition: opacity 0.18s ease;
}

/* Gated category row settled state - neutral, no score/warn signal. */
.sw-result-panel__check--locked {
    border-color: rgba(143, 163, 187, 0.20);
}

.sw-result-panel__cnt--locked {
    color: var(--sw-text-secondary);
}

.sw-result-panel__sdot--locked {
    background: var(--sw-text-secondary);
}

/* Score payoff: the number briefly grows, then settles back to size.
   Kept as a scale transform only (no colour/opacity flash) so it reads as
   a calm, single motivational beat rather than a "confetti" moment. */
.tryhook-payoff .sw-result-panel__sl-num {
    display: inline-block;
    transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
    transform: scale(1.28);
    transform-origin: left center;
}

.tryhook-payoff.tryhook-payoff--settled .sw-result-panel__sl-num {
    transform: scale(1);
}

/* Cliffhanger - "you saw the score, here's what's behind it" */
.tryhook-cliffhanger {
    max-width: 560px;
    margin: 1.75rem auto 0.75rem;
    text-align: center;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.5s ease, transform 0.5s ease;
}

.tryhook-cliffhanger.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.tryhook-cliffhanger h2 {
    font-size: var(--sw-text-2xl);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--sw-text);
    margin: 0 0 0.25rem;
}

.tryhook-cliffhanger p {
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    margin: 0;
}

/* Gate teaser - reuses the unchanged .sw-lead-lock-block partial, now living
   below the cliffhanger instead of inline in the scan panel. */
.sw-lead-lockblocks {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    max-width: 560px;
    margin: 0 auto;
}

/* Generic staggered fade/rise-in, shared by the gate teaser blocks and the
   grand-finale register CTA. */
.tryhook-stagger-in {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.45s ease, transform 0.45s ease;
}

.tryhook-stagger-in.is-visible {
    opacity: 1;
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .tryhook-payoff .sw-result-panel__sl-num,
    .tryhook-cliffhanger,
    .tryhook-stagger-in {
        transition-duration: 0.001ms !important;
        transform: none !important;
    }

}

@media (max-width: 767.98px) {
    .tryhook-cliffhanger {
        margin-left: 1rem;
        margin-right: 1rem;
    }

}

/* ── Admin Jobs ──
   Facelift for /admin/jobs: the page grew into six equal-weight stacked
   sections (queue depth, 3 KPI tiles, failed messages, scheduled tasks,
   registered jobs, raw message queue) that read as one long, misaligned
   list. Restructured into an always-visible "system health" snapshot
   (KPIs + queue depth + failed alert) followed by section tabs grouped by
   usage intent (action-oriented Failed messages, config-like Scheduled
   tasks, rarely-used Registered jobs, debug-only Message queue). */

.sw-jobs-health {
    display: flex;
    flex-direction: column;
    gap: 0;
}

/* Left-align (the marketing sw-feature-tabs default centers them) and allow
   horizontal scrolling instead of an awkward wrap on narrow admin viewports. */
.sw-jobs-tabs {
    justify-content: flex-start;
    margin-bottom: 1.5rem;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.sw-jobs-tabs::-webkit-scrollbar {
    display: none;
}

.sw-jobs-tabs .sw-feature-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
    flex-shrink: 0;
}

.sw-jobs-tab-badge {
    font-variant-numeric: tabular-nums;
}

.sw-jobs-failed-alert {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
}

.sw-jobs-failed-alert .sw-btn {
    margin-left: auto;
}

/* Queue-depth chip row: a plain wrapping flex row lets the last row leave a
   single narrow chip dangling on its own (the "gequetscht" look). A grid
   with a minimum column width distributes chips evenly instead. */
.sw-jobs-health .sw-queue-breakdown {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 0.5rem;
}

.sw-jobs-health .sw-queue-breakdown .sw-badge {
    justify-content: space-between;
    display: inline-flex;
    width: 100%;
}

/* Failed-messages / registered-jobs / message-queue tables: fixed column
   widths (via <colgroup>) keep Count/Time span/Actions from jumping around
   as the Error text length changes between polls - this was the "verschoben"
   look. Long error text truncates with an ellipsis; the full text is still
   available via the existing title="" tooltip. */
.sw-jobs-col-count {
    text-align: right;
}

.sw-jobs-failed-table td:nth-child(2) {
    max-width: 1px; /* forces the flexible column to respect the <colgroup> width */
    overflow: hidden;
}

.sw-jobs-failed-table td:nth-child(2) .sw-table-meta {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sw-jobs-failed-table td:nth-child(3) {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Message-queue table: the Shop cell (a raw URL) could wrap to 1 or 2 lines
   depending on domain length. Since the "processing" row's shop changes on
   every ~3s poll as the worker moves to the next message, an alternating
   1-line/2-line height made every row below visibly jump up and down on each
   poll. Single-line ellipsis truncation (full URL still in the title="")
   keeps row height constant. */
.sw-jobs-queue-table td:nth-child(3) {
    max-width: 1px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Scheduled-tasks config page (/admin/scheduled-tasks): descriptions run up
   to ~3 lines of prose, which made every row tall and the table feel long
   for what is a rarely-touched settings screen. Clamp to a single line with
   an ellipsis; the full text is still available via the title="" tooltip
   and in full on the per-task edit page. .sw-table uses table-layout: auto,
   so the <colgroup> widths are only hints - the cell itself needs the
   max-width/overflow clamp too, or the browser just grows the column to fit
   the untruncated text (same fix as .sw-jobs-queue-table above). */
.sw-scheduled-table td:nth-child(1) {
    max-width: 1px;
    overflow: hidden;
}

.sw-scheduled-desc {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sw-scheduled-table tbody tr:nth-child(even) {
    background: var(--sw-bg-subtle);
}

.sw-scheduled-table td {
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.sw-scheduled-task-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    color: var(--sw-text-muted);
}

.sw-scheduled-class-badge {
    margin-top: 0.375rem;
}

/* Failed-messages group-detail (expanded) table: same Shop-cell jump as the
   Message-queue table - the group re-fetches and re-renders on every 10s
   poll while expanded, so an unbounded-width URL cell caused the same
   1-line/2-line row-height flip. */
.sw-jobs-group-detail-table td:nth-child(1) {
    max-width: 1px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

@media (max-width: 767.98px) {
    .sw-jobs-health .sw-queue-breakdown {
        grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    }

    .sw-jobs-failed-alert .sw-btn {
        margin-left: 0;
        width: 100%;
        text-align: center;
    }

}

/* ── Metric detail: shared "Performed checks" shell ──
   Design-system classes replacing inline styles that were duplicated across
   6 score-metric pages (see account/_metric_checks.html.twig). */
.sw-md-section-title {
    font-size: var(--sw-text-2xl);
    font-weight: 600;
    margin: 1.5rem 0 1rem;
}
.sw-check-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}
.sw-check-row__icon { width: 20px; height: 20px; flex-shrink: 0; }
/* #920 (F-12): the description started wherever each name ended. From tablet
   width up the row is a grid, so every description starts on one line; a long
   name wraps inside its column. Mobile keeps the stacked layout below. */
@media (min-width: 768px) {
    .sw-check-row {
        display: grid;
        grid-template-columns: 20px minmax(9rem, 15rem) minmax(0, 1fr);
        column-gap: 0.75rem;
        align-items: baseline;
    }
    .sw-check-row__icon { align-self: center; }
}
.sw-check-row__icon--pass { color: var(--sw-success); }
.sw-check-row__icon--open { color: var(--sw-brand); }
.sw-check-row__name { font-weight: 600; }
.sw-check-row__desc { font-size: var(--sw-text-base); color: var(--sw-text-secondary); }

/* ── Metric detail: interpretation card ──
   Plain-language "what this means + biggest lever", keyed to the computed
   rating. Tinted neutral surface + coloured icon (no brand left-border);
   "poor" stays solution-oriented, never styled as an error. */

/* ── Feature "coming soon" card (e.g. per-page detail reports) ──
   Positive, centered card; light surface + blue accent, no brand left-border. */

/* ── Admin Revenue Widget ── */
.sw-revenue-stat {
    font-size: var(--sw-text-3xl);
    font-weight: 700;
    color: var(--sw-text);
    margin: 0 0 0.25rem;
}
.sw-revenue-stat .sw-dash-sub {
    font-size: var(--sw-text-base);
    font-weight: 500;
}

/* ── Dashboard Coach ("What you can do this week") ── */

/* FE-32: coach progress strip (since last week) */
.sw-coach__pchip { display: inline-flex; align-items: center; gap: .375rem; font-size: var(--sw-text-sm); font-weight: 600; border-radius: var(--sw-radius-btn); padding: .25rem .75rem; text-decoration: none; }
.sw-coach__pchip svg { width: 13px; height: 13px; }
.sw-coach__pchip--fixed { background: rgba(34,197,94,.14); color: var(--sw-success-dark); }
.sw-coach__pchip--new { background: var(--sw-warning-tint); color: var(--sw-warning-text); }
.sw-coach__pchip--regressed { background: var(--sw-danger-tint); color: var(--sw-poor-text); }
html.sw-dark .sw-coach__pchip--fixed { color: #4ADE80; }

/* ── FE-32: Verlauf (finding history) - contribution calendar + feed ── */
.sw-history-card { padding: 1.5rem 1.75rem; }
.sw-history-head {
    margin-bottom: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

/* First-run note: shown while a shop's calendar is still mostly empty, so the
   blank grid reads as "just getting started" rather than broken. Tinted
   background + brand icon (no brand-coloured left border, per convention). */
.sw-history-firstrun {
    display: flex;
    align-items: flex-start;
    gap: var(--sw-space-3);
    padding: var(--sw-space-4);
    margin-bottom: 1.25rem;
    background: var(--sw-brand-tint);
    border-radius: var(--sw-radius-inline);
}
.sw-history-firstrun__icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    color: var(--sw-brand-text);
}
.sw-history-firstrun__title {
    font-weight: 600;
    color: var(--sw-text);
    margin: 0 0 2px;
}
.sw-history-firstrun__body {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
    line-height: 1.55;
}
.sw-history-title { margin: 0 0 .25rem; }
.sw-history-sub { font-size: var(--sw-text-base); color: var(--sw-text-secondary); margin: 0; }
.sw-history-cal-wrap { position: relative; }
/* Column count and cell size come from the template (see history.html.twig):
   the grid runs from a few weeks old up to a full year, and 52 columns of 26px
   would be 1.6k pixels wide. Defaults here keep the legend cells correct, which
   render outside the sized container. */
.sw-history-cal { overflow-x: auto; padding-bottom: .25rem; --sw-hist-weeks: 13; --sw-hist-cell: 26px; --sw-hist-gap: 5px; }
.sw-history-months { display: grid; grid-template-columns: repeat(var(--sw-hist-weeks), var(--sw-hist-cell)); gap: var(--sw-hist-gap); margin-left: 40px; margin-bottom: .375rem; }
.sw-history-month { font-size: var(--sw-text-2xs); color: var(--sw-text-muted); white-space: nowrap; }
.sw-history-grid-row { display: flex; gap: .5rem; }
/* #536: sticky, not just first-in-flow - .sw-history-cal is the horizontal
   scroll container (overflow-x: auto), so without this the weekday column
   scrolls away with the oldest weeks the moment the grid is wider than the
   card (the history_calendar controller scrolls straight to the newest
   week). The opaque background covers scrolled-under grid cells. */
.sw-history-weekdays { display: grid; grid-template-rows: repeat(7, var(--sw-hist-cell)); gap: var(--sw-hist-gap); width: 32px; position: sticky; left: 0; background: var(--sw-surface); z-index: 1; }
.sw-history-weekdays span { font-size: var(--sw-text-xs); color: var(--sw-text-muted); line-height: var(--sw-hist-cell); }
.sw-history-grid { display: grid; grid-template-columns: repeat(var(--sw-hist-weeks), var(--sw-hist-cell)); gap: var(--sw-hist-gap); }
.sw-history-week { display: grid; grid-template-rows: repeat(7, var(--sw-hist-cell)); gap: var(--sw-hist-gap); }
/* A day is a quiet filled square, not a bordered box - borders on every cell
   made the grid read like an empty form (UI-Durchgang 2026-09-28). Only the
   two special states keep an outline, drawn as inset shadow. */
.sw-history-cell { width: var(--sw-hist-cell, 26px); height: var(--sw-hist-cell, 26px); border-radius: calc(var(--sw-hist-cell, 26px) / 4.5); background: var(--sw-history-cell-base); border: 0; box-sizing: border-box; }
/* Every day is a visible cell so the calendar always reads as a grid, even for a
   brand-new shop whose days are almost all before monitoring (#590). Inactive
   days (future / before the shop existed) are faint solid cells; a monitored day
   with no scan is a dashed outline; scanned days carry colour below. */
.sw-history-cell--future,
.sw-history-cell--before,
.sw-history-cell--empty { background: var(--sw-history-cell-noscan); }
.sw-history-cell--scan { background: var(--sw-history-cell-base); }
/* 424: monitoring-start anchor (inset brand border, not a glow ring) */
.sw-history-cell--start { box-shadow: inset 0 0 0 1.5px var(--sw-brand-strong); }
.sw-history-cell--f1 { background: rgba(34,197,94,.35); }
.sw-history-cell--f2 { background: rgba(34,197,94,.65); }
.sw-history-cell--f3 { background: var(--sw-success-dark); }
.sw-history-cell--regressed { box-shadow: inset 0 0 0 2px var(--sw-poor-text); }
/* A young calendar fills a third of its card. The day detail - where a tap or
   arrow key lands - takes the free column instead of a line underneath, so the
   card reads as one tool, not a small grid in an empty box. A long calendar
   (> 13 weeks) keeps the stacked layout. */
.sw-history-cal-layout { display: grid; grid-template-columns: max-content minmax(15rem, 1fr); gap: 1.5rem 2.5rem; align-items: start; }
.sw-history-cal-layout--long { grid-template-columns: minmax(0, 1fr); }
.sw-history-cal-side { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.sw-history-cal-side .sw-history-day-detail { margin: 0; padding: 1rem 1.125rem; border-radius: var(--sw-radius-inline); background: var(--sw-bg-subtle); color: var(--sw-text-secondary); font-size: var(--sw-text-base); line-height: 1.55; }
.sw-history-day-hint { margin: -.5rem 0 0; font-size: var(--sw-text-xs); color: var(--sw-text-muted); }
.sw-history-cal-side .sw-history-legend { margin: 0; flex-direction: column; align-items: flex-start; gap: .625rem; }
@media (max-width: 991.98px) {
    .sw-history-cal-layout { grid-template-columns: minmax(0, 1fr); }
    .sw-history-cal-side .sw-history-legend { flex-direction: row; flex-wrap: wrap; gap: .625rem 1.75rem; }
}

.sw-history-legend { display: flex; flex-wrap: wrap; align-items: center; gap: .625rem 1.75rem; margin-top: .875rem; margin-left: 40px; font-size: var(--sw-text-xs); color: var(--sw-text-muted); }
.sw-history-legend-item { display: inline-flex; align-items: center; gap: .375rem; white-space: nowrap; }
.sw-history-legend .sw-history-cell { flex-shrink: 0; }
.sw-history-feed { display: flex; flex-direction: column; gap: .75rem; }
.sw-history-feed-day { padding: 1.125rem 1.5rem; }
.sw-history-feed-date { font-size: var(--sw-text-sm); font-weight: 650; color: var(--sw-text-secondary); margin: 0 0 .625rem; }
.sw-history-feed-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.sw-history-feed-item { display: flex; align-items: center; gap: .625rem; flex-wrap: wrap; }
/* #536: the rule name is now a deep-link into the check's detail page - the
   global `a` rule already supplies the brand color and focus ring, so only
   the hover affordance needs adding here. */
.sw-history-feed-rule { font-size: var(--sw-text-md); font-weight: 500; }
.sw-history-feed-rule:hover { text-decoration: underline; }
.sw-history-feed-pts { font-size: var(--sw-text-sm); color: var(--sw-text-muted); margin-left: auto; white-space: nowrap; }

@media (max-width: 767.98px) {
    .sw-history-card { padding: 1.25rem 1rem; }

}

/* Billing: upgrade-resume interstitial (GET→checkout-POST handover) */
.sw-upgrade-resume { max-width: 480px; margin: 3rem auto; text-align: center; }
.sw-upgrade-resume__title { font-size: var(--sw-text-2xl); font-weight: 700; margin: 0 0 .375rem; }
.sw-upgrade-resume__sub { font-size: var(--sw-text-md); color: var(--sw-text-secondary); margin: 0 0 1.25rem; }

/* Coaching plan: locked step numbers sit back until unlocked */
.sw-nba-slot--frontier .sw-nba-step__num--locked,
.sw-nba-slot--queued .sw-nba-step__num--locked { background:var(--sw-bg-subtle); color:var(--sw-text-muted); border:1px solid var(--sw-border); }
@media (max-width: 767.98px) {
    .sw-nba-step { grid-template-columns: 1fr; }
    .sw-nba-step__num, .sw-nba-step::before { display:none; }
    .sw-nba__item { padding:1.25rem 1.25rem; }

}

/* Deep-linked check rows (from coach/action plan): clear the sticky navbar
   and flash briefly so the eye lands on the right section. */
.sw-check-row { scroll-margin-top: 96px; }
.sw-check-row:target { animation: sw-check-flash 1.6s ease-out 1; border-radius: var(--sw-radius-control); }
@keyframes sw-check-flash { 0% { background: var(--sw-brand-tint); } 100% { background: transparent; } }

/* Shared finding card (ADR-0008 AP-4): language-led finding with advisory
   impact pill and why/fix coaching prose. */
.sw-finding-card { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); padding: var(--sw-card-pad-md); }
.sw-finding-card__top { display: flex; align-items: baseline; gap: .625rem; margin-bottom: .5rem; }
.sw-finding-card__pts { font-size: var(--sw-text-xs); font-weight: 650; color: var(--sw-brand-text); background: var(--sw-brand-tint); border-radius: var(--sw-radius-btn); padding: .2rem .65rem; white-space: nowrap; }
.sw-finding-card__loc { font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-finding-card__message { margin: 0 0 .75rem; font-size: var(--sw-text-md); font-weight: 600; line-height: 1.5; }
.sw-finding-card__message:last-child { margin-bottom: 0; }
.sw-finding-card__code { margin-top: .875rem; }
.sw-finding-card .sw-nba__advice { margin-bottom: 0; }

/* Findings under an open check (shared findings_list macro) */
.sw-check-findings { margin: 0.5rem 0 1.5rem 1.75rem; }
.sw-check-findings__count { margin: 0 0 0.5rem; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-check-findings__stack { display: flex; flex-direction: column; gap: 0.75rem; }
.sw-check-findings__more { margin-top: 0.75rem; }
.sw-check-findings__stack--accordion { padding-left: 0.875rem; }
@media (max-width: 767.98px) { .sw-check-findings { margin-left: 0; } 
}

/* ── Metric-detail "Befund" hero (ADR-0008 AP-2) ──
   The advice sentence leads, the value is a stat pill, change/median are
   quiet side tiles. Rating tints stay advisory: poor is amber, never red. */
.sw-md-hero__befund { position: relative; overflow: hidden; background: var(--sw-bg); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 1.75rem 2rem; display: flex; flex-direction: column; gap: 1rem; }
.sw-md-hero__befund::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(560px 260px at 85% -20%, var(--sw-md-hero-glow, transparent), transparent 70%); }
.sw-md-hero__befund--good { --sw-md-hero-glow: rgba(34, 197, 94, .16); }
.sw-md-hero__befund--moderate { --sw-md-hero-glow: rgba(245, 158, 11, .14); }
.sw-md-hero__befund--poor { --sw-md-hero-glow: rgba(245, 158, 11, .2); }
.sw-md-hero__befund--none { --sw-md-hero-glow: rgba(59, 130, 246, .12); }
.sw-md-hero__eyebrow { display: flex; align-items: center; gap: .75rem; position: relative; }
.sw-md-hero__lead { position: relative; margin: 0; font-size: var(--sw-text-2xl); font-weight: 650; letter-spacing: -.015em; line-height: 1.55; }
.sw-md-hero__lead-icon { width: 22px; height: 22px; vertical-align: -4px; margin-right: .3rem; color: var(--sw-brand); }
.sw-md-hero__lead-icon--good { color: var(--sw-success); }
@media (max-width: 991.98px) {
    .sw-md-hero { grid-template-columns: 1fr; }

}

/* Metric detail: narrative structure (2026-08-04 iteration - "zu technisch
   und unstrukturiert"): one hero card with an inline stat meta row, named
   sections, background collapsed at the end. */
.sw-md-hero {
    grid-template-columns: 1fr;
    display: grid;
    gap: 1rem;
}
.sw-md-section-head { margin: 2.25rem 0 1rem; }
.sw-md-section-head .sw-md-section-title { margin: 0 0 .2rem; }
.sw-md-section-sub { margin: 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
/* #920 (F-07): the explainer sat flush under a preceding card (levers, competitor limit). Collapses with any bottom margin already there. */
.sw-md-background { margin-top: 1.5rem; }
/* #955 A-03: the explainer sits directly in the layout grid on the history page, where
   .sw-card's height:100% stretched the collapsed card to the column (830 px, footer over it). */
.sw-md-background.sw-card { height: auto; align-self: start; }
/* 2026-09-29 (S-4): collapsed, the explainer is one quiet line, not a 115 px
   empty card - the card padding moves to the summary and the body. */
.sw-md-background.sw-card { padding: 0; }
.sw-md-background.sw-card:hover { transform: none; box-shadow: none; }
.sw-md-background summary { list-style: none; }
.sw-md-background .sw-md-accordion-summary { padding: .875rem 1.25rem; font-size: var(--sw-text-md); border-radius: var(--sw-radius-card); }
.sw-md-background .sw-md-accordion-summary:hover { background: var(--sw-bg-subtle); }
.sw-md-background .sw-md-accordion-summary:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; }
.sw-md-background[open] .sw-md-accordion-summary { border-radius: var(--sw-radius-card) var(--sw-radius-card) 0 0; }
.sw-md-background__body { padding: .25rem 1.25rem 1.25rem; }
.sw-benchmark-verdict--better { color: var(--sw-success-dark); font-weight: 600; }
html.sw-dark .sw-benchmark-verdict--better { color: #4ADE80; }
.sw-benchmark-verdict--worse { color: var(--sw-text-secondary); font-weight: 600; }


/* Benchmark embedded in the metric hero (Befund card) */
.sw-md-hero__benchmark { position: relative; margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--sw-border); }
.sw-benchmark-embed .sw-benchmark-head { margin-bottom: .75rem; }

/* Embedded benchmark: slim, softened strip - no flags, no scale, no legend.
   Zone colours drop to tints so a red segment cannot shout inside a green
   Befund card; the verdict sentence turns into a quiet caption. */
.sw-benchmark-embed .sw-benchmark-track { height: 8px; margin: .75rem 0 .875rem; }
.sw-benchmark-embed--band .sw-benchmark-track { height: 14px; }
.sw-benchmark-embed .sw-benchmark-zone { opacity: .45; }
.sw-benchmark-embed .sw-benchmark-marker--own { height: 16px; top: -4px; }
.sw-benchmark-embed .sw-benchmark-verdict {
    font-weight: 600;
    margin: 0;
    font-size: var(--sw-text-md);
}
.sw-benchmark-embed .sw-benchmark-verdict--better { color: var(--sw-success-dark); }
html.sw-dark .sw-benchmark-embed .sw-benchmark-verdict--better { color: #4ADE80; }
.sw-benchmark-embed__caption { display: flex; flex-wrap: wrap; gap: .375rem 1.5rem; margin: .625rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
/* The caption is the key to the two ticks on the bar (#825), so each entry wears
   its tick: solid for the shop's own value, dashed for the median - the same
   shapes .sw-benchmark-marker draws. */
.sw-benchmark-key { display: inline-flex; align-items: center; gap: .4375rem; }
.sw-benchmark-key__mark { flex-shrink: 0; width: 3px; height: 14px; border-radius: 2px; }
.sw-benchmark-key__mark--own { background: var(--sw-text); }
.sw-benchmark-key__mark--median {
    background: repeating-linear-gradient(
        var(--sw-text-secondary),
        var(--sw-text-secondary) 3px,
        transparent 3px,
        transparent 6px
    );
}
.sw-benchmark-embed__caption b { color: var(--sw-text-secondary); font-weight: 600; font-variant-numeric: tabular-nums; }
.sw-benchmark-key__mark--band {
    width: 18px; height: 10px; border-radius: var(--sw-radius-xs);
    background: color-mix(in srgb, var(--sw-brand-light) 22%, transparent); border: 1.5px solid color-mix(in srgb, var(--sw-brand-light) 75%, transparent);
}
.sw-benchmark-key__mark--good { width: 12px; height: 10px; border-radius: var(--sw-radius-xs); background: var(--sw-success); opacity: .6; }

/* #1087: the shop's own normal range (min to max of the last 7 days) as a band
   behind the markers, so "today" reads as inside or outside it at a glance. */
.sw-benchmark-band {
    position: absolute; top: -5px; bottom: -5px; min-width: 6px;
    border-radius: var(--sw-radius-xs);
    background: color-mix(in srgb, var(--sw-brand-light) 22%, transparent); border: 1.5px solid color-mix(in srgb, var(--sw-brand-light) 75%, transparent);
}
.sw-md-hero__standing-title { position: relative; margin: 0 0 .25rem; font-size: var(--sw-text-md); font-weight: 650; color: var(--sw-text); }
.sw-md-hero__sentence { position: relative; margin: 0 0 1rem; max-width: 70ch; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-md-hero__sentence b { color: var(--sw-text); font-weight: 650; }
.sw-md-hero__benchmark .sw-md-hero__stale { max-width: 70ch; margin: 0 0 1rem; }
.sw-md-hero__since { position: relative; margin: .875rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }

/* Perfect chip: brand blue/white with a trophy Heroicon - clearly distinct
   from the amber moderate state (founder call) */
.sw-rating-chip__icon { width: 15px; height: 15px; color: var(--sw-brand-light); }
.sw-md-hero__befund--good:has(.sw-rating-chip--perfect) { --sw-md-hero-glow: rgba(59, 130, 246, .16); }

/* Perfect on the analytics overview: brand blue/white, distinct from moderate */

/* ── Competitor suggestions (FE-39) ──
   Sits directly under the add form: the empty domain field asks a question,
   this answers it. Rows are quiet and wide rather than card-like, so the block
   reads as a shortlist rather than a second data table. */
.sw-suggestions {
    margin: 0 0 var(--sw-space-5);
    padding: var(--sw-space-4);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    background: var(--sw-bg-subtle);
}

.sw-suggestions__head {
    margin-bottom: var(--sw-space-3);
}

.sw-suggestions__title {
    font-size: var(--sw-text-xl);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--sw-text);
    margin: 0 0 0.25rem;
}

.sw-suggestions__sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
    max-width: 62ch;
}

.sw-suggestions__list {
    gap: 0.375rem;
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.sw-suggestion {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6875rem 0.75rem;
    border-radius: var(--sw-radius-inline);
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.sw-suggestion:hover {
    border-color: var(--sw-brand);
    box-shadow: var(--sw-shadow-sm);
    transform: translateY(-1px);
}

.sw-suggestion__main {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    flex: 1;
}

.sw-suggestion__domain {
    font-size: var(--sw-text-md);
    font-weight: 600;
    color: var(--sw-text);
    overflow-wrap: anywhere;
}

/* The match reason (US-3): never a bare domain, never a raw cosine number. */
.sw-suggestion__reason {
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

/* The first row is the closest match by definition - the list is ordered by
   similarity. Worth one visual step up, and nothing more: the absolute tiers
   below it are not calibrated well enough to carry colour. */
.sw-suggestion__reason--top {
    color: var(--sw-brand-text);
    font-weight: 600;
}

/* Stacking the domain over its reason makes the row two lines tall, so the
   button needs to stop stretching with it. */
.sw-suggestion__form .sw-btn {
    white-space: nowrap;
}

.sw-suggestion__form {
    margin: 0;
    flex-shrink: 0;
}

/* Free teaser: placeholder bars only - the withheld domains never render. */

@media (max-width: 575.98px) {
    .sw-suggestion {
        flex-direction: column;
        align-items: flex-start;
    }

    .sw-suggestion__form {
        width: 100%;
    }

    .sw-suggestion__form .sw-btn {
        width: 100%;
        justify-content: center;
    }

}

/* ── Competitors page: the two top-level sections (comparison, manage) -
   Option B, #537. Whichever one renders second (order is state-dependent:
   see competitors.html.twig) gets breathing room above it, order-agnostic,
   same idiom as .sw-billing-zone + .sw-billing-zone. */
.sw-cmp-section + .sw-cmp-section {
    margin-top: var(--sw-space-8);
}

/* ── Competitor comparison: verdict + narrative groups (FE-39 follow-up) ──
   Same coaching anatomy as the metric-detail Befund hero: a sentence carries
   the finding, the numbers sit underneath as a quiet footnote. */
.sw-cmp-verdict {
    position: relative;
    overflow: hidden;
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-panel);
    padding: 1.75rem 2rem;
    margin-bottom: var(--sw-space-5);
}

.sw-cmp-verdict::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(560px 260px at 85% -20%, rgba(59, 130, 246, .12), transparent 70%);
}

.sw-cmp-verdict__lead {
    position: relative;
    margin: 0;
    font-size: var(--sw-text-2xl);
    font-weight: 650;
    letter-spacing: -.015em;
    line-height: 1.55;
    color: var(--sw-text);
}

.sw-cmp-verdict__sub {
    position: relative;
    margin: .5rem 0 0;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    max-width: 62ch;
}

/* Three equal columns so no single number reads as the headline. */
/* #849: aus drei Kacheln wird eine Zeile; der Trennstrich nach oben bleibt. */
.sw-cmp-verdict__stats {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--sw-border);
}

.sw-cmp-group {
    margin-bottom: var(--sw-space-5);
}

.sw-cmp-group__head {
    margin-bottom: var(--sw-space-3);
}

.sw-cmp-group__title {
    font-size: var(--sw-text-xl);
    font-weight: 650;
    letter-spacing: -.01em;
    color: var(--sw-text);
    margin: 0 0 .2rem;
}

.sw-cmp-group__sub {
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
    margin: 0;
    max-width: 62ch;
}

@media (max-width: 575.98px) {
    .sw-cmp-verdict {
        padding: 1.25rem 1.25rem;
    }

    .sw-cmp-verdict__stats {
        grid-template-columns: 1fr;
        gap: .75rem;
        text-align: left;
    }

}

the numbers are evidence, and a
   shop's health reads as a coloured aura before the score is parsed. */

.sw-brief { margin: 0 0 2.25rem; max-width: 74ch; }
.sw-brief__lede {
    font-size: var(--sw-text-4xl); line-height: 1.35; font-weight: 650; letter-spacing: -0.02em;
    margin: 0 0 1.25rem; text-wrap: balance;
}
/* The finding is part of the same sentence flow, just quieter than the count. */
.sw-brief__lede-detail { color: var(--sw-text-secondary); }
.sw-brief__evidence { margin: 0; align-items: center; }
.sw-brief__evidence .sw-headline-hint { margin-left: 0.15rem; }

.sw-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px,100%),1fr)); gap: 16px; }
.sw-tile-form { display: contents; }
.sw-tile {
    position: relative; isolation: isolate; overflow: hidden;
    display: block; width: 100%; text-align: left; cursor: pointer;
    padding: 1.15rem 1.25rem; border-radius: var(--sw-radius-card);
    border: 1px solid var(--sw-border); background: var(--sw-bg-subtle); color: inherit;
    transition: transform 0.18s cubic-bezier(0.22,1,0.36,1),
                border-color 0.18s cubic-bezier(0.22,1,0.36,1);
}
.sw-tile:hover { transform: translateY(-2px); }
.sw-tile:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; }
.sw-tile:active { transform: translateY(0); }

/* The aura itself: a radial wash bleeding in from the top-left, tinted by the
   rating band. Sits behind the content via z-index, never as a border. */
.sw-tile__aura {
    position: absolute; inset: 0; z-index: -1; pointer-events: none;
    opacity: 0.55; transition: opacity 0.18s cubic-bezier(0.22,1,0.36,1);
}
.sw-tile:hover .sw-tile__aura { opacity: 0.9; }
.sw-tile--good .sw-tile__aura { background: radial-gradient(120% 90% at 0% 0%, rgba(34,197,94,0.22), transparent 62%); }
.sw-tile--moderate .sw-tile__aura { background: radial-gradient(120% 90% at 0% 0%, rgba(245,158,11,0.22), transparent 62%); }
.sw-tile--poor .sw-tile__aura { background: radial-gradient(120% 90% at 0% 0%, rgba(239,68,68,0.24), transparent 62%); }
.sw-tile--analyzing .sw-tile__aura { background: radial-gradient(120% 90% at 0% 0%, rgba(148,163,184,0.16), transparent 62%); }
.sw-tile--good:hover { border-color: rgba(34,197,94,0.35); }
.sw-tile--moderate:hover { border-color: rgba(245,158,11,0.35); }
.sw-tile--poor:hover { border-color: rgba(239,68,68,0.38); }

.sw-tile__body { display: flex; flex-direction: column; gap: 0.6rem; }
.sw-tile__top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.sw-tile__dom { font-weight: 600; font-size: var(--sw-text-md); word-break: break-word; }
.sw-tile__score { display: inline-flex; align-items: center; gap: .4rem; }
.sw-tile__score .sw-light { margin-right: 0; }
.sw-tile__num {
    font-size: var(--sw-text-4xl); font-weight: 680; letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums; line-height: 1; flex: none;
}
.sw-tile__num--good { color: var(--sw-success); }
.sw-tile__num--moderate { color: var(--sw-warning); }
.sw-tile__num--poor { color: var(--sw-danger); }
.sw-tile__num--analyzing { color: var(--sw-text-muted); }
.sw-tile__state { display: flex; min-height: 1.5rem; align-items: center; }
.sw-tile__bar { display: block; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.08); overflow: hidden; }
.sw-tile__bar-fill { display: block; height: 100%; border-radius: 2px; }
.sw-tile__bar-fill--good { background: var(--sw-success); }
.sw-tile__bar-fill--moderate { background: var(--sw-warning); }
.sw-tile__bar-fill--poor { background: var(--sw-danger); }
.sw-tile__bar-fill--analyzing { background: var(--sw-text-muted); }

@media (max-width: 767.98px) {
    .sw-brief__lede { font-size: var(--sw-text-3xl); }

}
@media (prefers-reduced-motion: reduce) {
    .sw-tile, .sw-tile__aura { transition: none; }
    .sw-tile:hover { transform: none; }

}

/* Status key under the shop list/grid. Definition list so the badge and its
   explanation stay associated for screen readers. */
.sw-statuskey {
    display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 0.85rem;
    align-items: baseline; margin: 1rem 0 0; padding: 0.9rem 1.1rem;
    border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card);
    background: var(--sw-bg-subtle);
}
.sw-statuskey dt { margin: 0; }
.sw-statuskey dd {
    margin: 0; font-size: var(--sw-text-base); line-height: 1.5;
    color: var(--sw-text-secondary); max-width: 80ch;
}
@media (max-width: 575.98px) {
    .sw-statuskey { grid-template-columns: 1fr; gap: 0.3rem; }
    .sw-statuskey dd { margin-bottom: 0.5rem; }
    .sw-statuskey dd:last-child { margin-bottom: 0; }

}

/* ── /bot reference page ──────────────────────────────────────────────────
   Read by shop operators arriving from a server log or WAF dashboard, so it
   stays a reading column. The mascot carries the tone; the type stays plain. */
.sw-bot-hero .sw-hero { min-height: auto; padding: 2.5rem 0 2.5rem; }
/* Mascot centred above the headline: it is the greeting, so it leads. */
.sw-bot-hero__intro { display: flex; flex-direction: column; align-items: center; text-align: center; }
.sw-bot-hero__intro h1 { margin: 0 0 0.75rem; }
.sw-bot-hero__intro .sw-hero-sub { margin: 0 auto; max-width: 56ch; }
.sw-bot-hero__art { display: flex; justify-content: center; margin-bottom: 1.25rem; }

.sw-mascot { width: 220px; height: 220px; color: var(--sw-brand-light); flex: none; }
.sw-mascot__wave { transform-origin: 90px 82px; animation: sw-mascot-wave 2.6s ease-in-out 0.6s 3; }
.sw-mascot__blink { animation: sw-mascot-blink 4s ease-in-out infinite; }

@keyframes sw-mascot-wave {
      0%, 60%, 100% { transform: rotate(0deg); }
    70%             { transform: rotate(-16deg); }
    80%             { transform: rotate(8deg); }
    90%             { transform: rotate(-12deg); }
}
@keyframes sw-mascot-blink {
    0%, 92%, 100% { opacity: 1; }
    96%           { opacity: 0.35; }
}

.sw-bot { max-width: 72ch; }
.sw-bot__block { margin: 0 0 2.75rem; }
.sw-bot__block:last-child { margin-bottom: 0; }
.sw-bot__h { font-size: var(--sw-text-2xl); font-weight: 650; letter-spacing: -0.02em; margin: 0 0 0.6rem; }
.sw-bot__p { font-size: var(--sw-text-lg); line-height: 1.65; color: var(--sw-text-secondary); margin: 0 0 0.85rem; text-wrap: pretty; }
.sw-bot__label { font-size: var(--sw-text-base); font-weight: 600; margin: 0; }
.sw-bot__note { font-size: var(--sw-text-base); line-height: 1.55; color: var(--sw-text-muted); margin: 0; }
.sw-bot__list { margin: 0; padding-left: 1.15rem; display: flex; flex-direction: column; gap: 0.5rem; }
.sw-bot__list li { font-size: var(--sw-text-lg); line-height: 1.6; color: var(--sw-text-secondary); }
.sw-bot__link { color: var(--sw-brand-text); font-weight: 600; }

/* The promise block is the trust anchor of the page, so it gets its own
   surface. Ticks rather than bullets: each line is a commitment the reader can
   verify in their own logs, not a feature. */
.sw-bot__block--promises {
    padding: 1.5rem 1.6rem; border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-lg); background: var(--sw-bg-subtle);
}
.sw-bot__promises { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.75rem; }
.sw-bot__promises li { display: grid; grid-template-columns: auto 1fr; gap: 0.7rem; align-items: start; }
.sw-bot__promises span { font-size: var(--sw-text-lg); line-height: 1.6; color: var(--sw-text-secondary); }
.sw-bot__tick { width: 18px; height: 18px; margin-top: 0.28rem; color: var(--sw-success); flex: none; }

.sw-bot__agent { margin: 1.5rem 0 0; }
.sw-bot__agent-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.45rem; }
.sw-bot__ua {
    margin: 0 0 0.5rem; padding: 0.8rem 1rem; overflow-x: auto;
    border: 1px solid var(--sw-border); border-radius: var(--sw-radius-inline); background: var(--sw-bg-subtle);
}
.sw-bot__ua code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--sw-text-sm); color: var(--sw-text); white-space: pre; word-break: normal;
}
.sw-bot__copy {
    display: inline-flex; align-items: center; gap: 0.35rem; flex: none;
    padding: 0.3rem 0.7rem; border-radius: var(--sw-radius-btn);
    border: 1px solid var(--sw-border); background: transparent;
    color: var(--sw-text-secondary); font-size: var(--sw-text-sm); font-weight: 600; cursor: pointer;
    transition: background 0.18s cubic-bezier(0.22,1,0.36,1), color 0.18s cubic-bezier(0.22,1,0.36,1);
}
.sw-bot__copy svg { width: 15px; height: 15px; }
.sw-bot__copy:hover { background: rgba(255,255,255,0.05); color: var(--sw-text); }
.sw-bot__copy.is-copied { color: var(--sw-success); border-color: rgba(34,197,94,0.4); }

/* The closing sections are a pair (let us in / keep us out), so they sit side
   by side rather than stacking into a long tail. */
.sw-bot__split { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2.5rem; }
.sw-bot__split .sw-bot__block { margin-bottom: 0; }

@media (max-width: 767.98px) {
    .sw-mascot { width: 156px; height: 156px; }

}
@media (prefers-reduced-motion: reduce) {
    .sw-mascot__wave, .sw-mascot__blink { animation: none; }

}

/* ── Dashboard: stage + rail (docs/ux/dashboard-scope-2026-08-07.md) ────────
   The stage carries the one action of the week; the rail continues the week
   below it. Depth comes from nested surfaces (shell → core) and a rating-tinted
   glow, never from a coloured border. */

/* Doppelrand: the outer shell is a thin tray, the core sits inside it. */
/* #442-2 Variante B: coaching in a reading column, portfolio as a sticky rail
   filling the former dead space on the right. Single column on mobile and when
   there is no portfolio rail (one shop). */
.sw-dash-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
@media (min-width: 992px) {
    .sw-dash-split:has(.sw-dash-split__rail) {
        grid-template-columns: minmax(0, 68ch) minmax(0, 1fr);
        gap: 2rem;
        align-items: start;
    }
    .sw-dash-split__rail { position: sticky; top: 92px; }

}

.sw-stage {
    position: relative; margin: 0 0 0.25rem; padding: 6px;
    border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel);
    background: rgba(255,255,255,0.035);
}
.sw-stage__core {
    position: relative; overflow: hidden; border-radius: var(--sw-radius-panel);
    background: var(--sw-bg-subtle);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
    display: grid; grid-template-columns: 1.55fr 0.95fr;
}
.sw-stage__aura { position: absolute; inset: -40% 30% auto -20%; height: 420px; pointer-events: none; }
.sw-stage__aura--lever { background: radial-gradient(closest-side, rgba(245,158,11,0.20), transparent 72%); }
.sw-stage__aura--calm { background: radial-gradient(closest-side, rgba(59,130,246,0.16), transparent 72%); }
.sw-stage__main { position: relative; padding: 2rem 2rem 1.75rem; }
.sw-stage__step { display: inline-flex; align-items: center; gap: 0.55rem; margin: 0 0 0.9rem; }
.sw-stage__num {
    width: 26px; height: 26px; flex: none; border-radius: var(--sw-radius-btn);
    display: grid; place-items: center;
    font-size: var(--sw-text-xs); font-weight: 660; font-variant-numeric: tabular-nums;
    color: var(--sw-brand-light); background: rgba(59,130,246,0.14);
    box-shadow: 0 0 0 5px rgba(59,130,246,0.08);
}
.sw-stage__num svg { width: 14px; height: 14px; }
.sw-stage__label b { color: var(--sw-text-secondary); font-weight: 600; }
.sw-stage__what {
    font-size: var(--sw-text-2xl); line-height: 1.4; font-weight: 640;
    letter-spacing: -0.015em; margin: 0 0 0.65rem; text-wrap: pretty;
}
.sw-stage .sw-nba__advice { margin: 0 0 1.35rem; max-width: 54ch; }
.sw-stage__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin-bottom: 1rem; }
.sw-stage__meta {
    display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: center;
    font-size: var(--sw-text-sm); color: var(--sw-text-muted);
}
.sw-stage__impact { color: var(--sw-text); font-weight: 600; }
.sw-stage__gain { color: var(--sw-text-muted); font-weight: 500; }

/* sw-btn-cta / sw-btn-ghost now live in the core Buttons section (see near
   .sw-btn-outline) - moved there so they're documented system variants
   instead of a page-local parallel family. */

/* The pulse rides in the stage: portfolio number, week delta, distribution. */
.sw-pulse {
    position: relative; display: flex; flex-direction: column; gap: 1.15rem;
    padding: 1.75rem; border-left: 1px solid var(--sw-border);
    background: rgba(0,0,0,0.16);
}
.sw-pulse__label {
    margin: 0;
}
.sw-pulse__row { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.6rem; }
.sw-pulse__num {
    font-size: 2.25rem; font-weight: 680; letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums; line-height: 1;
}
.sw-pulse__delta { font-size: var(--sw-text-base); font-weight: 620; }
.sw-pulse__delta--down { color: var(--sw-danger); }
.sw-pulse__delta--up { color: var(--sw-success); }
.sw-pulse__spark { display: block; width: 100%; height: 44px; overflow: visible; }
.sw-pulse__rest {
    margin-top: auto; padding-top: 1rem; border-top: 1px solid var(--sw-border);
    display: flex; flex-direction: column; gap: 0.55rem;
}
.sw-pulse__item {
    display: flex; align-items: center; gap: 0.55rem; margin: 0;
    font-size: var(--sw-text-base); color: var(--sw-text-secondary);
}

/* The rail: reading column, one station per chapter. */
.sw-rail { position: relative; max-width: 70ch; margin: 2.25rem 0 0; padding-left: 2.75rem; }
.sw-rail::before {
    content: ""; position: absolute; left: 13px; top: -2.25rem; bottom: 1.5rem; width: 1px;
    background: linear-gradient(180deg, rgba(59,130,246,0.35), var(--sw-border) 22%, rgba(255,255,255,0.02));
}
.sw-step { position: relative; margin: 0 0 2.5rem; }
.sw-step:last-child { margin-bottom: 0; }
.sw-step__dot {
    position: absolute; left: -2.75rem; top: 1px; width: 27px; height: 27px;
    border-radius: var(--sw-radius-btn); background: var(--sw-bg); border: 1px solid var(--sw-border);
    display: grid; place-items: center;
    font-size: var(--sw-text-xs); font-weight: 660; font-variant-numeric: tabular-nums;
    color: var(--sw-text-secondary);
}
.sw-step__dot svg { width: 14px; height: 14px; }
.sw-step--act .sw-step__dot { border-color: rgba(59,130,246,0.35); color: var(--sw-brand-light); }
.sw-step__label {
    margin: 0 0 0.35rem;
}
.sw-step__h {
    margin: 0 0 0.55rem; font-size: var(--sw-text-xl); line-height: 1.4; font-weight: 640;
    letter-spacing: -0.015em; text-wrap: pretty;
}
.sw-step__p { margin: 0 0 1rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); text-wrap: pretty; }
.sw-step .sw-nba__advice { margin: 0 0 1rem; }
.sw-step__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.sw-step__gain { font-size: var(--sw-text-sm); color: var(--sw-success); font-weight: 620; }
.sw-step__who {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--sw-text-sm);
    color: var(--sw-text-muted); border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-btn); padding: 0.2rem 0.65rem;
}

/* Evidence card inside a chapter - nested again so it reads as inlaid, not stacked. */
.sw-inset {
    margin: 0 0 1.1rem; padding: 5px; border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-panel); background: rgba(255,255,255,0.03);
}
.sw-inset__core {
    padding: 1rem 1.15rem; border-radius: var(--sw-radius-card); background: var(--sw-bg-subtle);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
    display: flex; flex-direction: column; gap: 0.55rem;
}
.sw-chg {
    display: flex; align-items: flex-start; gap: 0.6rem; margin: 0;
    font-size: var(--sw-text-base); color: var(--sw-text-secondary);
}
.sw-chg svg { width: 15px; height: 15px; flex: none; margin-top: 0.22rem; }
.sw-chg b { color: var(--sw-text); font-weight: 600; }
.sw-chg--fixed svg { color: var(--sw-success); }
.sw-chg--new svg { color: var(--sw-warning); }
.sw-chg--back svg { color: var(--sw-poor-text); }
.sw-chg--locked svg { color: var(--sw-text-muted); }
.sw-chg--locked a { color: var(--sw-brand-text); }

/* A tile's own next action - the coaching isn't limited to the stage's shop. */
.sw-tile__next {
    display: flex; align-items: flex-start; gap: 0.45rem;
    padding-top: 0.75rem; border-top: 1px solid var(--sw-border);
    font-size: var(--sw-text-sm); line-height: 1.45; color: var(--sw-text-secondary);
    text-align: left; text-wrap: pretty;
}
.sw-tile__next svg { width: 14px; height: 14px; flex: none; margin-top: 0.15rem; color: var(--sw-brand-light); }

@media (max-width: 1100px) {
    .sw-stage__core { grid-template-columns: 1fr; }
    .sw-pulse { border-left: 0; border-top: 1px solid var(--sw-border); }

}
@media (max-width: 767.98px) {
    .sw-stage__main { padding: 1.4rem; }
    .sw-pulse { padding: 1.4rem; }
    .sw-stage__what { font-size: var(--sw-text-xl); }
    .sw-rail { padding-left: 2.25rem; margin-top: 1.75rem; }
    .sw-rail::before { left: 10px; }
    .sw-step__dot { left: -2.25rem; width: 22px; height: 22px; font-size: var(--sw-text-2xs); }

}
@media (prefers-reduced-motion: reduce) {
    .sw-btn-cta, .sw-btn-cta__ico, .sw-btn-ghost { transition: none; }

}

/* ── Turbo progress bar ────────────────────────────────────────────────
   Turbo injects its own stylesheet as the FIRST child of <head>, so these
   rules win simply by being loaded later - no !important needed.

   Turbo's default is a 3px #0076ff line that grows by a random fraction of
   a percent every 300ms. On a slow page that looks frozen, which is exactly
   when feedback matters most. The width still comes from Turbo (it is a
   guess, not real progress); the sweep is what tells you the app is working.
   The delay is set to 150ms in app.js. */
.turbo-progress-bar {
    height: 4px;
    background-color: var(--sw-brand);
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.55) 50%,
        transparent 100%
    );
    background-size: 180px 100%;
    background-repeat: no-repeat;
    animation: sw-progress-sweep 1.1s linear infinite;
}

@keyframes sw-progress-sweep {
    from { background-position: -180px 0; }
    to   { background-position: calc(100% + 180px) 0; }
}

@media (prefers-reduced-motion: reduce) {
    /* Keep the bar, drop the motion - it still grows, just without the sweep. */
    .turbo-progress-bar { animation: none; background-image: none; }

}

/* One shop: the selector slot names the shop instead of switching between them.
   Not a button, so it must not look or behave like one - no pointer, no hover
   border, and it sits back visually since there is nothing to press. */
.sw-shop-selector-toggle--static {
    cursor: default;
    background: var(--sw-bg-subtle);
}

.sw-shop-selector-toggle--static:hover {
    border-color: var(--sw-border);
}

/* ── Shop access notice ──
   Why a shop has no fresh data (blocked by a WAF, or simply unreachable), shown
   on the shop-scoped pages. Sits inside .sw-alert-warning, which is a flex row
   (icon + content), so the two lines get their own block to stack in. */
.sw-access-notice__body {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.sw-access-notice__lead,
.sw-access-notice__next {
    margin: 0;
}

.sw-access-notice__next {
    opacity: 0.9;
}

.sw-access-notice a {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* "Tell me when it ships" block inside coming-soon notices (_feature_notify.html.twig) */

/* ── Analytics v2 (Issue #320) ── */

/* Block C: bento category cards - 2x2 for the four weighted categories per the
   UX spec §5 (U-1); the fifth card (Agentic Commerce, the flagship, #624) spans
   the full width of its own row instead of sitting orphaned next to an empty cell. */
/* #975: six verdicts in a 3 x 2 strip of equal height - a head line, one state
   line, one quiet meta line. No card wider than the others; the flagship keeps
   its class only as a hook. */
.sw-av2-bento {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .75rem;
    margin-top: 1rem;
    align-items: stretch;
}
.sw-av2-card {
    display: flex;
    flex-direction: column;
    gap: .625rem;
    padding: .875rem 1rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    background: var(--sw-bg);
    text-decoration: none;
    color: inherit;
    transition: box-shadow .15s, transform .15s;
}
.sw-av2-card:hover {
    box-shadow: var(--sw-shadow-md);
    transform: translateY(-2px);
}
.sw-av2-card__head {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
}
.sw-av2-card .sw-card-icon { width: 28px; height: 28px; border-radius: var(--sw-radius-control); flex-shrink: 0; }
.sw-av2-card .sw-card-icon svg { width: 16px; height: 16px; }
/* Chip over count, always: side by side the pair wrapped in some cards and not
   in others, so six verdicts sat at six different heights (2026-09-28). */
.sw-av2-card__state { display: flex; flex-direction: column; align-items: flex-start; gap: .375rem; margin-top: auto; }
.sw-av2-card__chev { width: 16px; height: 16px; margin-left: auto; flex-shrink: 0; color: var(--sw-text-muted); transition: transform .15s, color .15s; }
.sw-av2-card:hover .sw-av2-card__chev { color: var(--sw-brand-text); transform: translateX(2px); }
@media (prefers-reduced-motion: reduce) { .sw-av2-card__chev { transition: none; } }
.sw-av2-card__count { font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-av2-card--neutral .sw-av2-card__count { color: var(--sw-text-muted); }
.sw-av2-card__meta { font-size: var(--sw-text-xs); color: var(--sw-text-muted); }
.sw-av2-card__stage { font-weight: 600; color: var(--sw-text-secondary); }
@media (max-width: 991.98px) {
    .sw-av2-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Block B: top action line - one sentence, one link (plan §3.3/3.4) */
.sw-av2-top-action {
    margin: 1rem 0 0;
    padding: .875rem 1.25rem;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    background: var(--sw-bg-subtle);
    font-size: var(--sw-text-md);
    line-height: 1.6;
    color: var(--sw-text);
}
.sw-av2-top-action a { color: var(--sw-brand-text); font-weight: 600; text-decoration: none; margin-left: .375rem; }
.sw-av2-top-action a:hover { text-decoration: underline; }
.sw-av2-top-action--perfect { color: var(--sw-success-text); }

/* Category section wrapper + "all clear" one-sentence replacement (UX §3.4.1) */
.sw-av2-section { margin-top: 1.5rem; }
.sw-av2-all-clear {
    margin: 0;
    padding: 1rem 1.25rem;
    border: 1px solid var(--sw-border);
    border-top: none;
    background: var(--sw-bg);
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-md);
}
.sw-av2-rows { display: flex; flex-direction: column; }

/* Row anatomy (UX §2): NOT a whole-row <a> like v1's sw-cmd-mrow - it carries
   prose, so the sentence is a <p> and "Fix ansehen" a normal, separately
   focusable link (interactive content is never nested inside another anchor -
   same rule as v1's metric_link macro). Name is allowed to wrap (no ellipsis,
   unlike v1) - a real coaching sentence must never be cut off (WCAG). */
.sw-av2-row {
    padding: .875rem 1.25rem;
    border: 1px solid var(--sw-border);
    border-top: none;
    background: var(--sw-bg);
}
.sw-av2-row:first-child {
    border-top: 1px solid var(--sw-border);
    border-top-left-radius: var(--sw-radius-card);
    border-top-right-radius: var(--sw-radius-card);
}
.sw-av2-row__top {
    display: flex;
    align-items: center;
    gap: .75rem;
}
.sw-av2-row__name {
    flex: 1;
    min-width: 0;
    font-size: var(--sw-text-base);
    font-weight: 600;
    color: var(--sw-text);
}
.sw-av2-row__val {
    font-variant-numeric: tabular-nums; /* #654: no mono in product chrome */
    font-size: var(--sw-text-base);
    font-weight: 600;
    white-space: nowrap;
}
.sw-av2-row__val small { color: var(--sw-text-muted); font-weight: 400; }
/* Free lock line (#337): rendered as the last row of the container so it
   sits inside the frame, not between the box and the green-rows toggle. */
.sw-av2-row--lock { background: var(--sw-bg-subtle); }
.sw-av2-row--lock .sw-av2-row__lead { margin-top: 0; }
.sw-av2-row__lead {
    margin: .5rem 0 0;
    font-size: var(--sw-text-base);
    line-height: 1.6;
    color: var(--sw-text-secondary);
}
.sw-av2-row__link {
    display: inline-flex;
    align-items: baseline;
    gap: .3em;
    color: var(--sw-brand-text);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
/* #505: arrow as ::after so it slides on hover; the literal glyph was removed
   from _av2_row.html.twig. Hover underlines and slides the arrow, focus-visible
   ring for keyboard users - clearly an action, still calm. */
.sw-av2-row__link::after {
    content: "\2192";
    transition: transform .15s ease;
}
.sw-av2-row__link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}
.sw-av2-row__link:hover::after { transform: translateX(3px); }
.sw-av2-row__link:focus-visible {
    outline: 2px solid var(--sw-brand);
    outline-offset: 2px;
    border-radius: var(--sw-radius-xs);
}

/* Free-plan lock line (row advice + Block B waiting state) - reduced, not
   blurred (UX §3.5): name/value/chip stay real, only this sentence is swapped. */
.sw-av2-lock {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    color: var(--sw-text-secondary);
}
.sw-av2-lock svg { width: 15px; height: 15px; flex-shrink: 0; }
.sw-av2-lock a { color: var(--sw-brand-text); font-weight: 600; text-decoration: none; }
.sw-av2-lock a:hover { text-decoration: underline; }

/* "N more in the green zone" - same idiom as .sw-score-explainer: native
   <details>, aufklappen bleibt instant (no height-transition), only the
   marker rotates (UX §4.2). */
.sw-av2-more {
    border: 1px solid var(--sw-border);
    border-top: none;
    background: var(--sw-bg-subtle);
}
.sw-av2-more-toggle {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .75rem 1.25rem;
    cursor: pointer;
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-brand-text);
    list-style: none;
}
.sw-av2-more-toggle::-webkit-details-marker { display: none; }
.sw-av2-more-toggle svg { width: 14px; height: 14px; transition: transform 150ms ease-out; }
.sw-av2-more[open] .sw-av2-more-toggle svg { transform: rotate(90deg); }
.sw-av2-more .sw-av2-rows { border-top: 1px solid var(--sw-border); }
.sw-av2-more .sw-av2-row:first-child { border-top: none; border-radius: 0; }

@media (prefers-reduced-motion: reduce) {
    .sw-av2-more-toggle svg { transition: none; }

}

.sw-av2-row[id] {
    scroll-margin-top: calc(var(--sw-navbar-height) + 12px);
}

@media (max-width: 767.98px) {
    /* One column on mobile (UX §5, U-1). */
    .sw-av2-bento {
        grid-template-columns: 1fr;
    }
    /* Name gets its own full-width line, value + chip flow together on the
       line below (UX §5) - opposite of v1's fixed-column single-line row. */
    .sw-av2-row__top {
        flex-wrap: wrap;
        row-gap: .375rem;
    }
    .sw-av2-row__name {
        flex-basis: 100%;
    }

}

/* ── Profile: settings in panels (#1038, founder 2026-09-29 "gefällt mir überhaupt
   nicht"). Replaces the card-less list of #503: on a wide screen a label at the
   far left and its field at the far right read as two unrelated things. Now the
   page speaks the app's panel standard (#1033): a compact identity row, the
   tabs (#814), and per tab one or two panels - fields stacked label over input,
   switches and states at the row's end. ── */

.seta-identity { display: flex; align-items: center; gap: 1rem; margin: 0 0 1.5rem; }
.seta-avatar { width: 52px; height: 52px; border-radius: 50%; overflow: hidden; flex-shrink: 0; display: block; }
.seta-identity__text { min-width: 0; }
.seta-identity__name { font-size: var(--sw-text-lg); font-weight: 600; color: var(--sw-text); margin: 0; }
.seta-identity__email { font-size: var(--sw-text-base); color: var(--sw-text-secondary); margin: .125rem 0 0; overflow-wrap: anywhere; }
.seta-identity__meta { font-size: var(--sw-text-sm); color: var(--sw-text-muted); margin: .25rem 0 0; }

.seta-tabs { display: flex; gap: .25rem; box-shadow: inset 0 -1px 0 var(--sw-border); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.seta-tabs::-webkit-scrollbar { display: none; }
.seta-tab { flex: 0 0 auto; padding: .75rem 1rem; font-size: var(--sw-text-md); font-weight: 500; white-space: nowrap; color: var(--sw-text-secondary); background: none; border: 0; border-bottom: 2px solid transparent; cursor: pointer; transition: color .15s, border-color .15s; }
.seta-tab:hover { color: var(--sw-text); }
.seta-tab.sw-tab-active { color: var(--sw-brand-text); border-bottom-color: var(--sw-brand-text); }
.seta-tab:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: -2px; border-radius: var(--sw-radius-sm) var(--sw-radius-sm) 0 0; }
@media (prefers-reduced-motion: reduce) { .seta-tab { transition: none; } }

.seta-panel { padding-top: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }

/* Every section is a panel - the same surface, hairline, radius and padding as
   every other framed block in the app. */
.seta-section { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); padding: var(--sw-card-pad-md); }
.seta-section__title { font-size: var(--sw-text-lg); font-weight: 600; letter-spacing: -.01em; color: var(--sw-text); margin: 0; }
.seta-section__sub { font-size: var(--sw-text-base); color: var(--sw-text-secondary); margin: .25rem 0 0; max-width: 62ch; }
.seta-section__title + .seta-section__sub { margin-top: .25rem; }

/* Stacked fields: label, one line of help, the input - one reading line. */
.seta-fields { display: flex; flex-direction: column; gap: 1.25rem; margin-top: 1.25rem; max-width: 460px; }
.seta-field { display: flex; flex-direction: column; gap: .375rem; }
.seta-field .seta-row__label, .seta-field label { font-size: var(--sw-text-base); font-weight: 600; color: var(--sw-text); margin: 0; }
.seta-field__help { font-size: var(--sw-text-sm); color: var(--sw-text-muted); margin: 0; line-height: 1.5; }
.seta-input { width: 100%; }
/* The sign-in address is not editable: it reads like a field, visibly locked. */
.seta-value { display: flex; align-items: center; gap: .5rem; padding: .625rem .875rem; border: 1px dashed var(--sw-border); border-radius: var(--sw-radius-control); background: var(--sw-bg-subtle); font-size: var(--sw-text-md); color: var(--sw-text-secondary); overflow-wrap: anywhere; }
.seta-value svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--sw-text-muted); }
.seta-actions { display: flex; justify-content: flex-start; margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--sw-border); }

/* Rows: label and help left, the switch, button or state at the end. */
.seta-row { display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; padding: 1rem 0; border-top: 1px solid var(--sw-border); }
.seta-section > .seta-row:first-child, .seta-section__sub + .seta-row, .seta-section__sub + ul .seta-row:first-child { margin-top: .75rem; }
.seta-section > .seta-row:first-child { margin-top: 0; border-top: 0; padding-top: 0; }
.seta-row:last-child { padding-bottom: 0; }
.seta-row__main { min-width: 0; flex: 1; }
.seta-row__label { font-size: var(--sw-text-md); font-weight: 600; color: var(--sw-text); margin: 0; }
.seta-row__label--danger { color: var(--sw-poor-text); }
.seta-row__desc { font-size: var(--sw-text-sm); color: var(--sw-text-secondary); margin: .25rem 0 0; line-height: 1.55; max-width: 60ch; }
.seta-row__control { flex-shrink: 0; display: flex; align-items: center; gap: .75rem; justify-content: flex-end; }

@media (max-width: 640px) {
    .seta-row { flex-direction: column; align-items: flex-start; gap: .75rem; }
    .seta-row__control { justify-content: flex-start; }
    .seta-fields { max-width: none; }
}

/* #385: uptime "no probe yet" pending note - shown instead of a fabricated 100%
   before the first probe has run (grey bars accompany it). */
.sw-uptime-side-pending { margin: .25rem 0 0; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-cmd-uptime__pending { font-size: var(--sw-text-sm); color: var(--sw-text-muted); }

/* Lead share (FE-46/GTM-1) - copy-link + share-intent row inside .sw-lead-cta.
   Reuses sw-btn/sw-btn-outline/sw-btn-sm as-is; only the row layout and the
   icon+label gap inside these specific buttons are new. Tokens only, so it
   holds up in dark mode without an override block. */
.sw-lead-share {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--sw-border);
}

.sw-lead-share__label {
    font-size: var(--sw-text-sm);
    font-weight: 500;
    color: var(--sw-text-muted);
    margin: 0 0 0.75rem;
}

.sw-lead-share__actions {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.sw-lead-share__actions .sw-btn {
    gap: 0.4rem;
}

.sw-lead-share__actions svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* ── Async toggle inline confirmation (#531) ── */
.sw-toggle-status {
    font-size: var(--sw-text-sm);
    font-weight: 500;
    white-space: nowrap;
    transition: opacity 0.2s ease;
}
.sw-toggle-status--ok { color: var(--sw-success, #22c55e); }
.sw-toggle-status--err { color: var(--sw-danger-dark, #DC2626); }
@media (prefers-reduced-motion: reduce) { .sw-toggle-status { transition: none; } 
}
/* In a settings row the confirmation sits under the switch, out of flow: the
   control is right-aligned, so a status in flow would push the switch left the
   moment it appears. */
.seta-row__control > form { position: relative; }
.seta-row__control .sw-toggle-status { position: absolute; top: calc(100% + .25rem); right: 0; }
/* Mobile: the switch is left-aligned, so the status can sit beside it. */
@media (max-width: 640px) { .seta-row__control .sw-toggle-status { top: 50%; right: auto; left: calc(100% + .75rem); transform: translateY(-50%); } }

/* Footer rotating tagline (breadth over a single uptime claim) */
.sw-footer-tagline {
    transition: opacity 0.4s ease;
    display: inline-block;
}
.sw-footer-tagline.is-fading {
    opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
    .sw-footer-tagline {
        transition: none;
    }

}

/* FE-35 Agentic Commerce: Automation Curve maturity badge (#608).
   Token-based so it works in the dark theme; scoped, additive. */
.sw-agentic-curve {
    background: var(--sw-bg);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    box-shadow: var(--sw-shadow-sm);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}
.sw-agentic-curve__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.sw-agentic-curve__eyebrow { display: block; }
.sw-agentic-curve__title { font-size: var(--sw-text-3xl); font-weight: 700; color: var(--sw-text); margin: .25rem 0 0; }
.sw-agentic-curve__badge { flex-shrink: 0; font-size: var(--sw-text-sm); font-weight: 600; color: var(--sw-text-secondary); background: var(--sw-bg-subtle); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-btn); padding: .35rem .75rem; white-space: nowrap; }
.sw-agentic-curve__lead { color: var(--sw-text-secondary); font-size: var(--sw-text-md); margin: .75rem 0 1.5rem; max-width: 65ch; }
.sw-agentic-curve__rail { list-style: none; display: grid; grid-template-columns: repeat(6, 1fr); gap: .5rem; margin: 0; padding: 0; }
.sw-agentic-curve__step { position: relative; display: flex; flex-direction: column; align-items: center; gap: .4rem; text-align: center; }
.sw-agentic-curve__step::before { content: ''; position: absolute; top: 1rem; left: -50%; width: 100%; height: 2px; background: var(--sw-border); z-index: 0; }
.sw-agentic-curve__step:first-child::before { display: none; }
.sw-agentic-curve__num { position: relative; z-index: 1; width: 2rem; height: 2rem; display: grid; place-items: center; border-radius: var(--sw-radius-btn); font-size: var(--sw-text-sm); font-weight: 700; background: var(--sw-bg-subtle); color: var(--sw-text-muted); border: 2px solid var(--sw-border); }
.sw-agentic-curve__label { font-size: var(--sw-text-xs); color: var(--sw-text-muted); line-height: 1.25; }
.sw-agentic-curve__soa { font-size: var(--sw-text-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--sw-brand-text); }
.sw-agentic-curve__step--done .sw-agentic-curve__num { background: var(--sw-brand-tint); color: var(--sw-brand-text); border-color: var(--sw-brand-tint); }
.sw-agentic-curve__step--done::before { background: var(--sw-brand); }
.sw-agentic-curve__step--current .sw-agentic-curve__num { background: var(--sw-brand-strong); color: #fff; border-color: var(--sw-brand-strong); box-shadow: 0 0 0 4px var(--sw-brand-tint); }
.sw-agentic-curve__step--current::before { background: var(--sw-brand); }
.sw-agentic-curve__step--current .sw-agentic-curve__label { color: var(--sw-text); font-weight: 600; }
.sw-agentic-curve__step--future { opacity: .5; }
.sw-agentic-curve__attribution { margin: 1rem 0 0; font-size: var(--sw-text-xs); color: var(--sw-text-muted); }
.sw-agentic-perf { margin: 0 0 1.5rem; padding: .875rem 1rem; border-radius: var(--sw-radius-card); background: var(--sw-bg-subtle); border: 1px solid var(--sw-border); color: var(--sw-text-secondary); font-size: var(--sw-text-md); }
.sw-agentic-perf--good { color: var(--sw-text); }
.sw-agentic-perf--slow { border-color: var(--sw-warning-border, var(--sw-border)); }
/* Mobile: the stage names ARE the content, so the rail becomes a vertical
   list (number + name per row) instead of six bare circles (#623). */
@media (max-width: 640px) {
    .sw-agentic-curve__rail { grid-template-columns: 1fr; gap: .5rem; }
    .sw-agentic-curve__step { flex-direction: row; align-items: center; text-align: left; gap: .75rem; }
    .sw-agentic-curve__step::before { display: none; }
    .sw-agentic-curve__num { flex-shrink: 0; }
    .sw-agentic-curve__label { font-size: var(--sw-text-base); }
    .sw-agentic-curve__soa { margin-left: auto; font-size: var(--sw-text-2xs); }
    .sw-agentic-curve__head { flex-direction: column; }

}

/* ── First-score moment and score lead (#629) ── */
.sw-first-score { border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); background: var(--sw-brand-tint); padding: 1rem 1.25rem; margin-bottom: 1rem; }
.sw-first-score__title { margin: 0 0 .25rem; font-weight: 700; color: var(--sw-text); }
.sw-first-score__verdict { margin: 0; color: var(--sw-text-secondary); font-size: var(--sw-text-md); }
.sw-cmd-score-lead { margin: 0 0 .5rem; font-size: var(--sw-text-md); color: var(--sw-text); max-width: 34ch; }
.sw-cmd-score-stat__value--neutral { color: var(--sw-text-muted); }
/* ── /agentic story page (#627) ── */
.sw-agentic-hero__form { margin-top: 1.5rem; }
.sw-agentic-stakes { padding-bottom: 0; }
.sw-agentic-stakes__text { max-width: 44rem; margin: 0 auto; text-align: center; font-size: var(--sw-text-2xl); line-height: 1.6; color: var(--sw-text); }
.sw-agentic-example { max-width: 52rem; margin: 2rem auto 0; }
.sw-agentic-step { position: relative; }
.sw-agentic-step__num { display: inline-block; font-size: var(--sw-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--sw-brand-text); background: var(--sw-brand-tint); border-radius: var(--sw-radius-btn); padding: .2rem .65rem; margin-bottom: .75rem; }
.sw-agentic-sources { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: .75rem; }
.sw-agentic-sources li { display: flex; flex-direction: column; gap: .15rem; padding: .75rem 1rem; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); background: var(--sw-bg-subtle); }
.sw-agentic-sources__fact { color: var(--sw-text); font-size: var(--sw-text-md); }
.sw-agentic-sources__src { color: var(--sw-text-muted); font-size: var(--sw-text-sm); }
.sw-agentic-sources__note { margin-top: 1rem; }
@media (min-width: 768px) { .sw-agentic-sources { grid-template-columns: 1fr 1fr; } 
}
/* ── /try result: what the account adds (#625) ── */
.sw-result-panel__more { margin: .75rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }

/* ── Performance score: the biggest levers (#633) ── */
.sw-perf-levers { margin-top: 1.5rem; }
.sw-perf-levers__title { font-size: var(--sw-text-xl); font-weight: 600; margin: 0 0 .25rem; }
.sw-perf-levers__sub { color: var(--sw-text-secondary); font-size: var(--sw-text-md); margin: 0 0 1rem; }
.sw-perf-levers__list { margin: 0; padding-left: 1.25rem; display: grid; gap: .875rem; }
.sw-perf-levers__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .375rem .75rem; }
.sw-perf-levers__name { font-weight: 600; }
.sw-perf-levers__savings { background: var(--sw-brand-tint); color: var(--sw-brand-text); }
.sw-perf-levers__desc { color: var(--sw-text-secondary); font-size: var(--sw-text-md); margin: .25rem 0 0; }
/* ── Profile: alert catalogue (#631) ── */
.sw-watch-list { list-style: none; margin: 0; padding: 0; }
.sw-badge-locked { background: var(--sw-bg-subtle); color: var(--sw-text-secondary); border: 1px solid var(--sw-border); }

/* ── Page report: lead sentence, pending components (#634) ── */
.sw-page-report__lead { font-size: var(--sw-text-xl); color: var(--sw-text); margin: 0 0 1.25rem; max-width: 64ch; }
.sw-cmd-score-stat__pending { font-size: var(--sw-text-sm); font-weight: 500; color: var(--sw-text-muted); }
.sw-page-report__pending { text-align: left; }
.sw-page-report__pending-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .375rem; }
.sw-page-report__pending-list li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .25rem 1rem; color: var(--sw-text); font-size: var(--sw-text-md); }
.sw-page-report__pending-note { color: var(--sw-text-muted); font-size: var(--sw-text-base); }

/* ── /try results: running state, failed checks, unreachable (#637) ── */
.sw-result-panel__running { display: flex; flex-wrap: wrap; align-items: center; gap: .375rem .5rem; margin: .625rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-result-panel__running-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sw-brand); animation: sw-running-pulse 1.4s ease-in-out infinite; }
.sw-result-panel__running-elapsed { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--sw-text); }
.sw-result-panel__running-hint { color: var(--sw-text-muted); }
/* #915: once the promised window has passed the line is one long sentence. It
   wraps inside its own text, while the dot stays beside the first line instead
   of sitting alone above it. */
.sw-result-panel__running.is-overdue { flex-wrap: nowrap; align-items: flex-start; }
.sw-result-panel__running.is-overdue .sw-result-panel__running-dot { flex: none; margin-top: .4em; }
.sw-result-panel__track--pending { position: relative; }
.sw-result-panel__track--pending .sw-result-panel__track-fill { width: 0 !important; }
.sw-result-panel__track--pending::after { content: ""; position: absolute; inset: 0; width: 40%; border-radius: var(--sw-radius-btn); background: linear-gradient(90deg, transparent, rgba(59, 130, 246, .55), transparent); animation: sw-track-indeterminate 1.6s ease-in-out infinite; }
.sw-result-panel__cnt--failed { color: var(--sw-text-muted); }
.sw-result-panel__sdot--failed { background: var(--sw-text-muted); }
.sw-result-panel__check--failed .sw-result-panel__check-ic { opacity: .6; }
.sw-lead-lock-badge--pending { background: rgba(143, 163, 187, .14); color: var(--sw-text-secondary); }
.sw-lead-lock-badge--failed { background: rgba(143, 163, 187, .14); color: var(--sw-text-muted); }
.sw-lead-unreachable { margin: 1.25rem 0; }
.sw-lead-unreachable__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin: 0 0 2rem; }
@keyframes sw-running-pulse { 0%, 100% { opacity: .35; transform: scale(.85); } 50% { opacity: 1; transform: scale(1); } }
@keyframes sw-track-indeterminate { 0% { transform: translateX(-100%); } 100% { transform: translateX(260%); } }
@media (prefers-reduced-motion: reduce) {
    .sw-result-panel__running-dot { animation: none; }
    .sw-result-panel__track--pending::after { animation: none; width: 100%; opacity: .5; }

}

/* ── /try results: median line, reduced motion (#638) ── */
.sw-result-panel__median { margin: .5rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
@media (prefers-reduced-motion: reduce) {
    .sw-result-panel__spinner { animation: none; border-top-color: rgba(143, 163, 187, 0.6); }
    .sw-result-panel__track-fill { transition: none !important; }

}

/* ── Registration from /try: known shop (#639) ── */
.sw-auth2__known { margin-left: .5rem; font-size: var(--sw-text-2xs); vertical-align: middle; }

/* ── Auth card family: legal line (#640) ── */
.sw-auth2__legal { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: .5rem 1.125rem; margin: 1.25rem auto 0; max-width: 25rem; text-align: center; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-auth2__legal-link { color: inherit; text-decoration: none; display: inline-block; padding-block: .35rem; }
.sw-auth2__legal-link:hover { color: var(--sw-text); text-decoration: underline; }

/* ── Focus visible, product-wide (#648) ──
   Every non-anchor control gets a ring that clears 3:1 (dark: --sw-brand-light,
   9.6:1 against the page). Component rules that draw their own ring override
   this; the ones that removed the outline without a replacement no longer can. */
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible {
    outline: 2px solid var(--sw-focus-ring);
    outline-offset: 2px;
}
.sw-tab:focus-visible {
    outline: 2px solid var(--sw-focus-ring);
    outline-offset: -2px;
}
.sw-nba__domain-input:focus-visible,
.sw-firstrun__input:focus-visible,
.sw-empty-add__input:focus-visible {
    outline: 2px solid var(--sw-focus-ring);
    outline-offset: 1px;
}
html.sw-dark .sw-btn-danger {
    color: var(--sw-poor-text) !important; /* #648: 6.3:1 inside a subtle card too */
    border-color: var(--sw-poor-text);
}

/* ── Tap targets on mobile (#649): 44px for everything a thumb has to hit ── */
@media (max-width: 767.98px) {
    .sw-tab,
    .sw-feature-tab,
    .sw-sidebar-link,
    .sw-pager .sw-btn,
    .sw-btn-sm {
        min-height: 44px;
    }
    .sw-billing-invoices-inline__link,
.sw-locale-link {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }
    .sw-locale-link {
        padding: 0 0.75rem;
    }

}

/* ── Skip target (#650): the landmark takes focus without a stray ring ── */
.sw-main:focus,
.sw-main-public:focus {
    outline: none;
}

/* ── Reduced motion, product-wide (#651) ──
   25 animations, 18 of them endless, used to run regardless of the OS
   preference. One rule at the end of the cascade ends them all; component
   rules above only refine what stays (static end states). */
@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;
    }

}

/* ── Mobile 390px (#652): tables scroll, rows stack, nothing pushes the page ──
   .sw-table clips (overflow: hidden for the rounded corners), so wide cells were
   cut off instead of scrollable; 97 of 114 tables have no wrapper. Below 768px
   every table becomes its own horizontal scroll container. */
@media (max-width: 767.98px) {
    .sw-table,
    .sw-invoice-table,
    .sw-competitor-table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .sw-table-wrapper {
        max-width: 100%;
    }

    /* Check rows: name and description stack instead of breaking mid-word. */
    .sw-check-row {
        flex-wrap: wrap;
        align-items: flex-start;
    }
    .sw-check-row__name,
    .sw-check-row__desc {
        overflow-wrap: anywhere;
    }
    .sw-check-row__desc {
        flex-basis: 100%;
        padding-left: calc(20px + 0.5rem);
    }

    /* Long URLs (page reports, shop headers) wrap instead of widening the header.
       `white-space` has to come back to normal with it (#870): the desktop rule
       sets `nowrap` for the one-line-with-ellipsis look, and a line that may not
       break cannot be broken by `overflow-wrap` either - a long enough title then
       widens the whole layout viewport instead of wrapping. The title selector
       repeats the desktop one (0,2,0): a bare class (0,1,0) loses to it (#1072). */
    .sw-account-header .sw-account-header__title,
    .sw-account-header__sub {
        overflow-wrap: anywhere;
        white-space: normal;
    }

    /* The analysis status line goes under its track instead of beside it. */
    .sw-analyzing-bar {
        flex-wrap: wrap;
    }
    .sw-analyzing-bar__text {
        white-space: normal;
        flex-basis: 100%;
    }

}

@media (max-width: 575.98px) {
    /* Metric rows reserved 332px of fixed columns: drop the sparkline, tighten
       value and status so the name keeps room on a 390px screen. */
    .sw-cmd-mrow {
        grid-template-columns: minmax(0, 1fr) 5.5rem 6rem 16px;
        gap: .5rem;
        padding: .75rem 1rem;
    }

}

/* The content landmark of the account and admin shells (#653): a grid child
   must be allowed to shrink, or a wide table pushes the sidebar. */
.sw-main {
    min-width: 0;
}

/* ── Dashboard (#655): eyebrow instead of a second h1, tiles as links, filter empty state ── */
.sw-account-header__eyebrow { margin: 0 0 .125rem; }
a.sw-tile, a.sw-dash3-table__dom { text-decoration: none; }
a.sw-tile:hover { color: inherit; }
.sw-dash3-chip__count { margin-left: .25rem; font-variant-numeric: tabular-nums; color: var(--sw-text-muted); }
.sw-dash3-chip.is-active .sw-dash3-chip__count { color: inherit; }
.sw-dash3-empty { margin-bottom: 1rem; }

/* ── Confirmation dialog (#658) ── */
.sw-confirm-modal__body { margin: 0 0 1.25rem; color: var(--sw-text-secondary); line-height: 1.55; }
.sw-confirm-nojs { display: inline-flex; align-items: center; gap: .5rem; margin-right: .75rem; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }

/* ── Metric shell states (#660): running scan, deferred PSI measurement, stale reading ── */
.sw-metric-analyzing { display: flex; flex-direction: column; gap: .5rem; }
.sw-metric-analyzing__title { margin: 0; font-size: var(--sw-text-xl); font-weight: 600; color: var(--sw-text); }
.sw-metric-analyzing__text { margin: 0 0 .5rem; color: var(--sw-text-secondary); font-size: var(--sw-text-md); max-width: 60ch; }
.sw-metric-analyzing .sw-analyzing-bar { margin-top: .25rem; }
.sw-metric-analyzing .sw-poll-timeout { margin-top: .75rem; }
.sw-metric-deferred-note { margin: 0 0 1.5rem; }
.sw-md-hero__stale { display: block; margin-top: .25rem; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); max-width: 32ch; }

/* ── Reach-100 jump list + checks that never ran (#661) ── */
.sw-md-jumplist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .375rem; counter-reset: sw-jump; }
.sw-md-jumplist__item { counter-increment: sw-jump; }
.sw-md-jumplist__link { display: flex; align-items: center; gap: .625rem; padding: .625rem .75rem; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-inline); background: var(--sw-bg-subtle); color: var(--sw-text); text-decoration: none; }
.sw-md-jumplist__link:hover { border-color: var(--sw-border-strong); color: var(--sw-text); }
.sw-md-jumplist__link::before { content: counter(sw-jump); flex: 0 0 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--sw-brand-tint); color: var(--sw-brand-text); font-size: var(--sw-text-xs); font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.sw-md-jumplist__name { flex: 1 1 auto; font-weight: 600; }
.sw-md-jumplist__count { color: var(--sw-text-secondary); font-size: var(--sw-text-sm); white-space: nowrap; }
.sw-md-jumplist__chevron { width: 16px; height: 16px; flex: 0 0 auto; color: var(--sw-text-muted); }
.sw-md-jumplist__hint { margin: .75rem 0 0; color: var(--sw-text-muted); font-size: var(--sw-text-sm); }
.sw-check-row__icon--skipped { color: var(--sw-text-muted); }
.sw-check-row--skipped .sw-check-row__name { color: var(--sw-text-secondary); }
/* #1047: on a phone the row is a small grid - number left, the name with its
   count underneath, the chevron right and centred - instead of wrapping into
   three loose lines with the chevron alone at the bottom. */
@media (max-width: 575.98px) {
    .sw-md-jumplist__link { display: grid; grid-template-columns: 1.5rem minmax(0, 1fr) auto; column-gap: .75rem; row-gap: .125rem; align-items: center; padding: .75rem .875rem; }
    .sw-md-jumplist__link::before { grid-column: 1; grid-row: 1 / span 2; }
    .sw-md-jumplist__name { grid-column: 2; grid-row: 1; overflow-wrap: anywhere; }
    .sw-md-jumplist__count { grid-column: 2; grid-row: 2; white-space: normal; }
    .sw-md-jumplist__chevron { grid-column: 3; grid-row: 1 / span 2; }
}

/* ── Metric shell polish (#663): card titles, chart block, chip variants, calmer delta ── */
.sw-md-card-title { display: block; font-size: var(--sw-text-2xl); font-weight: 600; margin: 0; color: var(--sw-text); }
.sw-md-card-title--block { margin-bottom: 1rem; }
.sw-md-card-title--tight { margin-bottom: .5rem; }
.sw-md-card-sub { margin: 0 0 1rem; color: var(--sw-text-secondary); font-size: var(--sw-text-md); }
.sw-placeholder-card__title { margin: 0 0 .5rem; font-size: var(--sw-text-xl); font-weight: 600; color: var(--sw-text); }
.sw-md-chart { display: flex; flex-direction: column; gap: .75rem; }
.sw-md-chart__toggle { align-self: flex-end; }
.sw-md-chart__box { height: 300px; }
.sw-md-chart__summary { margin: 0; }
.sw-md-chart__legend { margin: 0; }
.sw-benchmark-verdict--par { color: var(--sw-text-secondary); font-weight: 600; }
/* A value drifting the wrong way is advice, not an alarm (ADR-0008, MET-39). */
@media (max-width: 575.98px) {
    .sw-md-chart__toggle { align-self: stretch; }
}

/* ── Markup roadmap (#664): causes as numbered steps, occurrences behind a disclosure ── */
.sw-markup-roadmap { margin-top: 1.5rem; }
.sw-markup-roadmap__title { font-size: var(--sw-text-xl); font-weight: 600; margin: 0 0 .25rem; color: var(--sw-text); }
.sw-markup-roadmap__sub { margin: 0 0 1rem; color: var(--sw-text-secondary); font-size: var(--sw-text-md); max-width: 65ch; }
.sw-markup-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .75rem; }
.sw-markup-step { border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); background: var(--sw-surface, var(--sw-bg)); padding: 1rem 1.25rem; }
.sw-markup-step__head { display: flex; gap: .75rem; align-items: flex-start; }
.sw-markup-step__num { flex: 0 0 1.75rem; height: 1.75rem; border-radius: 50%; background: var(--sw-brand-tint); color: var(--sw-brand-text); font-size: var(--sw-text-sm); font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.sw-markup-step__body { min-width: 0; flex: 1 1 auto; }
.sw-markup-step__message { margin: 0 0 .375rem; font-weight: 600; color: var(--sw-text); overflow-wrap: anywhere; }
.sw-markup-step__meta { margin: 0 0 .5rem; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-markup-step__tone { display: inline-flex; align-items: center; padding: .125rem .5rem; border-radius: var(--sw-radius-btn); font-size: var(--sw-text-xs); font-weight: 600; background: var(--sw-bg-subtle); color: var(--sw-text-secondary); }
.sw-markup-step__tone--error { background: var(--sw-warning-tint); color: var(--sw-warning-text); }
.sw-markup-step__tone--warning { background: var(--sw-brand-tint); color: var(--sw-brand-text); }
.sw-markup-step__fix { margin: 0 0 .5rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-markup-step__fix strong { color: var(--sw-text); }
.sw-markup-step__where { margin-top: .25rem; }
.sw-markup-occurrence { padding: .5rem 0; border-top: 1px solid var(--sw-border); }
.sw-markup-occurrence:first-child { border-top: 0; padding-top: 0; }
.sw-markup-occurrence__line { display: block; font-size: var(--sw-text-sm); color: var(--sw-text-muted); margin-bottom: .25rem; }
.sw-markup-occurrence__code { margin: 0; }
.sw-markup-step__more, .sw-markup-roadmap__note { margin: .5rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-markup-rest { margin-top: 1rem; }
.sw-markup-rest__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.sw-markup-rest__item { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; font-size: var(--sw-text-md); }
.sw-markup-rest__message { flex: 1 1 20ch; overflow-wrap: anywhere; }
.sw-markup-rest__count { color: var(--sw-text-muted); font-size: var(--sw-text-sm); white-space: nowrap; }
.sw-markup-roadmap__cap { margin: 1rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); max-width: 65ch; }
html.sw-dark .sw-markup-step__tone--error { color: var(--sw-warning); }

/* ── Uptime bar (#665): visible "no data" cells, weekly bar on phones, hints, text table ── */
.sw-uptime-bar-no_data { background: var(--sw-uptime-nodata); opacity: 1; }
.sw-uptime-bar--weeks { display: none; }
.sw-uptime-side-hint { margin: .375rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); line-height: 1.45; }
.sw-uptime-side-hint a { color: var(--sw-brand-text); font-weight: 600; }
.sw-uptime-list { margin: .5rem 0 1rem; }
.sw-uptime-list__table { margin: 0; }
.sw-uptime-list__none { margin: 0; color: var(--sw-text-secondary); font-size: var(--sw-text-md); }
@media (max-width: 767.98px) {
    .sw-uptime-bar--days { display: none; }
    .sw-uptime-bar--weeks { display: block; }
    .sw-uptime-bar--weeks .sw-uptime-bar-track { gap: 4px; }
}

/* ── Uptime story (#666): context under the percentage, runbook, alert promise ── */
.sw-uptime-side-context { margin: .5rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); line-height: 1.45; }
.sw-uptime-side-period { margin: .25rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-uptime-runbook__title { margin: 0 0 .25rem; font-weight: 600; color: var(--sw-text); }
.sw-uptime-runbook__sub { margin: 0 0 .75rem; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
.sw-uptime-runbook__steps { margin: 0; padding-left: 1.25rem; display: flex; flex-direction: column; gap: .5rem; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
.sw-uptime-runbook__steps a { color: var(--sw-brand-text); font-weight: 600; }
.sw-uptime-alert-card__title { margin: 0 0 .375rem; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-weight: 600; color: var(--sw-text); }
.sw-uptime-alert-card__text { margin: 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); line-height: 1.45; }

/* ── Competitors (#667): limit card, pending verdict, failed scan, poll status, notify feedback ── */
.sw-cmp-limit-card__title { font-size: var(--sw-text-xl); font-weight: 600; margin: 0 0 .375rem; color: var(--sw-text); }
/* #920 (F-08): `.sw-card p` zeroes the bottom margin and out-ranks a lone class - the CTA stuck to the text. */
.sw-card .sw-cmp-limit-card__body { margin: 0 0 1rem; color: var(--sw-text-secondary); font-size: var(--sw-text-md); max-width: 60ch; }
.sw-cmp-limit-card__passive { margin: 0; color: var(--sw-text-muted); font-size: var(--sw-text-base); }
.sw-cmp-verdict--pending .sw-cmp-verdict__lead { color: var(--sw-text-secondary); }
.sw-cmp-verdict__basis { margin: .25rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-competitor-na--error { color: var(--sw-warning-text); font-weight: 600; }
html.sw-dark .sw-competitor-na--error { color: var(--sw-warning); }
.sw-competitor-error-note { margin: .5rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-competitor-poll-status { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 1rem 0 0; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-competitor-notify-feedback { display: block; margin-top: .25rem; font-size: var(--sw-text-xs); color: var(--sw-text-muted); min-height: 1em; }

/* ── Techstack page (#668): moved out of the template body ── */

/* ── Techstack states (#668) ── */
.sw-ts-state__icon { width: 48px; height: 48px; margin-bottom: 1rem; color: var(--sw-text-muted); }
.sw-ts-state__title { margin: 0 0 .5rem; font-size: var(--sw-text-xl); font-weight: 600; color: var(--sw-text); }
.sw-ts-state__body { margin: 0 auto; max-width: 48ch; color: var(--sw-text-secondary); }
.sw-ts-state__body a, .sw-ts-state-note a, .sw-ts-vulnerable__hint a { color: var(--sw-brand-text); font-weight: 600; }
.sw-ts-state .sw-poll-timeout { margin-top: 1rem; text-align: left; }
.sw-ts-state-note { margin: 0 0 1rem; padding: .75rem 1rem; border-radius: var(--sw-radius-inline); background: var(--sw-warning-tint); color: var(--sw-text); font-size: var(--sw-text-md); }
.sw-ts-vulnerable { margin-bottom: 1.5rem; }
.sw-ts-vulnerable__title { margin: 0 0 .5rem; font-weight: 600; color: var(--sw-text); }
.sw-ts-vulnerable__list { margin: 0 0 .75rem; padding-left: 1.25rem; color: var(--sw-text-secondary); font-size: var(--sw-text-md); }
.sw-ts-vulnerable__hint { margin: 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }

/* ── History and shop detail polish (#669) ── */
.sw-history-cal:focus-visible { outline: 2px solid var(--sw-focus-ring); outline-offset: 2px; border-radius: var(--sw-radius-sm); }
.sw-history-cell:focus-visible, .sw-history-cell.is-active { outline: 2px solid var(--sw-focus-ring); outline-offset: 1px; }
.sw-history-day-detail { margin: .75rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); min-height: 1.4em; }
.sw-history-mobile-note { display: none; margin: .25rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-history-blocked .sw-history-firstrun__body a { color: var(--sw-brand-text); font-weight: 600; }
.sw-history-feed-score { margin: -.25rem 0 .5rem; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-analysis-badge--inline { display: inline-flex; }
.sw-shop-add--narrow { max-width: 640px; }
@media (max-width: 767.98px) {
    /* 52 weeks at 13px are noise on a phone: show the last 13 weeks, large enough to tap. */
    .sw-history-cal-wrap--long .sw-history-cal { --sw-hist-cell: 22px !important; --sw-hist-gap: 4px !important; }
    .sw-history-cal-wrap--long .sw-history-grid, .sw-history-cal-wrap--long .sw-history-months { grid-template-columns: repeat(13, var(--sw-hist-cell)) !important; }
    .sw-history-cal-wrap--long .sw-history-week:nth-last-child(n+14), .sw-history-cal-wrap--long .sw-history-month:nth-last-child(n+14) { display: none; }
    .sw-history-cal-wrap--long .sw-history-mobile-note { display: block; }
}

/* ── Checkout modal (#670): labelled fields, inline errors, gross total ── */
.sw-checkout-field { display: flex; flex-direction: column; gap: .25rem; }
.sw-checkout-field .sw-form-label { margin: 0; }
.sw-checkout-field__hint { margin: -.25rem 0 0; }
.sw-checkout-required { color: var(--sw-danger-dark); }
.sw-checkout-required-hint { font-weight: 400; color: var(--sw-text-muted); margin-left: .25rem; }
.sw-checkout-summary--total { display: flex; flex-direction: column; gap: .25rem; margin: 1rem 0 0; }
.sw-checkout-summary__line { display: flex; justify-content: space-between; gap: 1rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-checkout-summary__total { padding-top: .375rem; border-top: 1px solid var(--sw-border); color: var(--sw-text); font-weight: 600; }
.sw-checkout-form input[aria-invalid="true"] { border-color: var(--sw-danger); }

/* ── Payment return and hub (#671) ── */
.sw-billing-retry { margin: 1rem 0 .5rem; }
.sw-billing-return__secondary { display: inline-block; margin-top: .5rem; color: var(--sw-brand-text); font-weight: 600; }
.sw-billing-return__next-title { margin: 1rem 0 .25rem; font-weight: 600; color: var(--sw-text); }
.sw-billing-return__next { margin: 0 0 1rem; padding-left: 1.25rem; color: var(--sw-text-secondary); }
.sw-billing-return__next a { color: var(--sw-brand-text); }
.sw-upgrade-resume__intervals { border: 0; padding: 0; margin: 1rem 0; display: flex; flex-direction: column; gap: .5rem; }
.sw-upgrade-resume__option { display: flex; align-items: center; gap: .5rem; padding: .625rem .75rem; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-inline); cursor: pointer; }
.sw-upgrade-resume__option:has(input:checked) { border-color: var(--sw-brand); background: var(--sw-brand-tint); }

/* #672: billing polish - token badges instead of inline rgba, over-limit notes, upsell limits */

.sw-billing-usage-fill--over {
    background: var(--sw-warning);
}

.sw-billing-usage-over {
    margin: 0.5rem 0 0;
    font-size: var(--sw-text-sm);
    line-height: 1.5;
    color: var(--sw-text-secondary);
}

.sw-shop-list-over-limit {
    margin: 0 0 1rem;
    font-size: var(--sw-text-base);
    line-height: 1.5;
    color: var(--sw-text-secondary);
}

.sw-shop-list-over-limit a {
    color: var(--sw-brand-text);
    font-weight: 600;
}

.sw-upsell-limits {
    margin: 0.75rem 0 0;
    max-width: 44ch;
    font-size: var(--sw-text-md);
    line-height: 1.6;
    color: var(--sw-text-secondary);
}

/* #673: shops and teams - explicit role save, explained locks, quick-add fee note */
.sw-team-role-form {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.sw-ws-section-hint {
    align-self: center;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-muted);
}

.sw-empty-add__price {
    margin: 0 0 0.75rem;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

/* #676: local initials avatars - the SVG takes the size and radius of the slot it replaces */
.sw-avatar {
    display: inline-block;
    vertical-align: middle;
}

.sw-avatar text {
    user-select: none;
}

/* #678: admin actions report their outcome next to the control */
.sw-check-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* ── #680 Admin: states, accessibility and the last inline styles ── */
.sw-form-card { max-width: 560px; }
.sw-inline-form { display: inline; }
.sw-btn-svg { width: 16px; height: 16px; }
.sw-btn-svg--lead { width: 18px; height: 18px; margin-right: 0.375rem; }
.sw-placeholder-icon { width: 28px; height: 28px; margin-bottom: 0.5rem; }
.sw-placeholder-icon--ok { color: var(--sw-success-dark); }
.sw-revenue-chart { position: relative; height: 220px; }
.sw-revenue-chart-empty { min-height: 220px; display: flex; align-items: center; justify-content: center; }
/* Dashboard shortcut cards are links: the whole card is the target, the heading answers the hover. */
.sw-card-link { display: block; color: inherit; text-decoration: none; }
.sw-card-link:hover,
.sw-card-link:focus-visible { color: inherit; }
.sw-card-link:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; }
.sw-card-link h3 { transition: color 0.15s ease; }
.sw-card-link:hover h3 { color: var(--sw-brand-text); }
/* Failed-message groups open from a real button (ADM-45); the chevron follows aria-expanded. */
.sw-queue-group-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.sw-queue-group-toggle:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; border-radius: var(--sw-radius-xs); }
.sw-queue-group-chevron { width: 14px; height: 14px; flex-shrink: 0; transition: transform 0.15s ease; }
.sw-queue-group-toggle[aria-expanded="true"] .sw-queue-group-chevron { transform: rotate(90deg); }
.sw-queue-group-detail > td { background: var(--sw-bg-subtle); }
@media (prefers-reduced-motion: reduce) {
    .sw-queue-group-chevron,
    .sw-card-link h3 { transition: none; }
}

/* ── #682 Public feedback dialog trigger + /bot contact line ── */
.sw-public-feedback { display: inline-flex; }
.sw-bot__contact { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.75rem; margin: 0 0 0.75rem; }

/* The short real preview above a gate block: a calm line, a caption, no axes. */
.sw-score-preview__chart {
    height: 140px;
    padding: 0;
}

.sw-score-preview__caption {
    margin: 0.5rem 0 0;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

/* ── Gate pattern (docs/ux/gating-pattern-2026-09-04.md) ──────────────────────
   One pattern for every locked surface: real data or none, benefit first, one
   action. Three building blocks and nothing else. No blur, no overlay, no
   vignette, no skeleton bars, no lock icon in the block, no sample data, no
   brand-coloured left border. What used to be six hand-built overlays lives
   here once. */

.sw-gate-block {
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 1.5rem;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

/* Inside an existing card: tinted on tinted reads as a bug, so only the border carries it. */
.sw-gate-block--inline {
    background: transparent;
    padding: 1.25rem;
}

/* Directly under a real preview: the two read as one thought, not two blocks. */
.sw-gate-block--continues {
    margin-top: 0.75rem;
}

/* The whole page is the gate. Text stays left aligned, the block is centred. */
.sw-gate-block--page {
    max-width: 34rem;
    margin-inline: auto;
}

.sw-gate-block__eyebrow {
    margin: 0;
}

.sw-gate-block__title {
    margin: 0;
    font-size: var(--sw-text-xl);
    font-weight: 600;
    color: var(--sw-text);
}

.sw-gate-block__body {
    margin: 0;
    font-size: var(--sw-text-md);
    line-height: 1.55;
    color: var(--sw-text-secondary);
    max-width: 52ch;
}

.sw-gate-block__list {
    list-style: none;
    margin: 0.25rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.sw-gate-block__list-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
}

.sw-gate-block__list-item svg {
    flex-shrink: 0;
    margin-top: 0.1875rem;
    color: var(--sw-text-secondary);
}

.sw-gate-block__actions {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: 0.375rem;
    flex-wrap: wrap;
}

.sw-gate-block__link,
.sw-gate-note__link {
    color: var(--sw-brand-text);
    font-weight: 600;
    font-size: var(--sw-text-md);
    text-decoration: none;
}

.sw-gate-block__link:hover,
.sw-gate-note__link:hover {
    text-decoration: underline;
}

.sw-gate-note__title {
    display: block;
    color: var(--sw-text);
}

.sw-gate-block__secondary {
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-base);
}

.sw-gate-block__owner-note,
.sw-gate-note__owner {
    margin: 0;
    font-size: var(--sw-text-base);
    color: var(--sw-text-secondary);
}

/* The note: the page is complete, the plan only makes more of it. */
.sw-gate-note {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    padding: 0.875rem 1.125rem;
}

.sw-gate-note__text {
    margin: 0;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
    flex: 1 1 24rem;
}

/* The row: a list that already shows real entries is missing further ones. */
.sw-gate-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 0.75rem 0 0;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
}

.sw-gate-row svg {
    flex-shrink: 0;
    color: var(--sw-text-secondary);
}

.sw-gate-row a {
    color: var(--sw-brand-text);
    font-weight: 600;
    text-decoration: none;
}

.sw-gate-row a:hover {
    text-decoration: underline;
}

@media (max-width: 767.98px) {
    .sw-gate-block {
        padding: 1.25rem;
    }

    .sw-gate-block__actions {
        flex-direction: column;
        align-items: stretch;
    }

    .sw-gate-block__actions .sw-btn {
        width: 100%;
        min-height: 44px;
    }

    .sw-gate-note {
        flex-direction: column;
        align-items: stretch;
    }

    .sw-gate-note .sw-btn {
        width: 100%;
        min-height: 44px;
    }
}

/* ── Preisseite: Fokus-Karten plus Vergleichstabelle (#841) ──
   Der Gründer fand die Seite "billo": drei gleich schwere Kästen, kleine Preise,
   lange Listen. Die Karten entscheiden jetzt (eine hervorgehobene Stufe, großer
   Preis, wenige Unterschiede), die Tabelle darunter beweist. */
.sw-pricing-plans .sw-pricing-card {
    padding: 2.25rem 2rem;
    border-radius: var(--sw-radius-panel);
    gap: .125rem;
}
.sw-pricing-plans .sw-pricing-card--featured {
    padding: 2.75rem 2.25rem;
    background:
        linear-gradient(180deg, rgba(59, 130, 246, .10), rgba(59, 130, 246, .02) 55%, transparent),
        var(--sw-surface);
    border-color: rgba(59, 130, 246, .45);
    box-shadow: 0 20px 60px -30px rgba(59, 130, 246, .75);
}
.sw-pricing-plans .sw-pricing-tier {
    font-size: var(--sw-text-xl);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--sw-text);
    text-transform: none;
}
.sw-pricing-plans .sw-pricing-amount {
    font-size: 3rem;
    font-weight: 800;
    letter-spacing: -0.04em;
    font-variant-numeric: tabular-nums;
    line-height: 1.05;
}
.sw-pricing-plans .sw-pricing-tagline {
    font-size: var(--sw-text-base);
    line-height: 1.5;
    color: var(--sw-text-secondary);
    margin-bottom: 1.25rem;
    min-height: 2.6em;
}
.sw-pricing-plans .sw-pricing-cta {
    margin-top: .25rem;
    margin-bottom: 1.5rem;
}
.sw-pricing-plans .sw-pricing-includes {
    margin-bottom: .625rem;
}
.sw-pricing-plans .sw-pricing-trust {
    gap: 1rem 2.5rem;
    margin-top: 3rem;
    font-size: var(--sw-text-md);
}

/* Die Tabelle: eine Zeile je Merkmal, vier Gruppen, mitlaufende Kopfzeile. */
.sw-pricing-compare { padding-top: 0; }
.sw-pricing-compare__sub {
    margin: -.5rem 0 1.75rem;
    color: var(--sw-text-secondary);
    font-size: var(--sw-text-md);
    text-align: center;
}
.sw-cmp { max-width: 980px; margin: 0 auto; }
.sw-cmp__head {
    position: sticky;
    top: 0;
    z-index: 20;
    display: grid;
    grid-template-columns: 1.5fr repeat(3, 1fr);
    gap: 1rem;
    padding: .75rem 0;
    background: var(--sw-bg);
    border-bottom: 1px solid var(--sw-border);
}
.sw-cmp__head > div {
    text-align: center;
    font-size: var(--sw-text-xs);
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--sw-text-muted);
}
.sw-cmp__head > div:first-child { text-align: left; color: var(--sw-text-secondary); }
.sw-cmp__head--focus { color: var(--sw-brand-text) !important; }
.sw-cmp__group {
    margin: 2.25rem 0 0;
    font-size: var(--sw-text-xs);
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--sw-brand-text);
}
.sw-cmp__row {
    display: grid;
    grid-template-columns: 1.5fr repeat(3, 1fr);
    gap: 1rem;
    align-items: center;
    padding: .9375rem 0;
    border-top: 1px solid var(--sw-border);
    font-size: var(--sw-text-md);
}
.sw-cmp__label b { display: block; font-weight: 600; color: var(--sw-text); }
.sw-cmp__label span { font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-cmp__cell { text-align: center; color: var(--sw-text-secondary); font-variant-numeric: tabular-nums; }
.sw-cmp__cell--focus { background: rgba(59, 130, 246, .06); border-radius: var(--sw-radius-control); padding: .375rem 0; }
.sw-cmp-yes { color: var(--sw-success-text); font-weight: 600; }
.sw-cmp-no { color: var(--sw-text-muted); }

@media (max-width: 767.98px) {
    .sw-pricing-plans .sw-pricing-card--featured { padding: 2.25rem 1.75rem; }
    .sw-pricing-plans .sw-pricing-tagline { min-height: 0; }
    .sw-cmp__head { display: none; }
    .sw-cmp__row { grid-template-columns: 1fr; gap: .375rem; }
    .sw-cmp__cell { text-align: left; }
    .sw-cmp__cell::before { content: attr(data-plan) ": "; color: var(--sw-text-muted); }
    .sw-cmp__cell--focus { padding: .375rem .5rem; }
}

/* ── Agentic: die vier Dimensionen für Free (#847) ──
   Nur Name und Ampel je Dimension. Keine Check-Namen, keine Befunde - die
   Ampel sagt, wo es steht, die Maßnahmen darunter sagen, was zu tun ist. */
.sw-agentic-dims { list-style: none; margin: .75rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.sw-agentic-dim {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .875rem 1.125rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card);
    font-size: var(--sw-text-md);
}
.sw-agentic-dim__light { flex-shrink: 0; width: 10px; height: 10px; border-radius: var(--sw-radius-btn); background: var(--sw-text-muted); }
.sw-agentic-dim__name { flex: 1; min-width: 0; font-weight: 600; color: var(--sw-text); }
.sw-agentic-dim__state { flex-shrink: 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-agentic-dim--good .sw-agentic-dim__light { background: var(--sw-success); }
.sw-agentic-dim--good .sw-agentic-dim__state { color: var(--sw-success-text); }
.sw-agentic-dim--moderate .sw-agentic-dim__light { background: var(--sw-warning); }
.sw-agentic-dim--moderate .sw-agentic-dim__state { color: var(--sw-warning-text); }
.sw-agentic-dim--poor .sw-agentic-dim__light { background: var(--sw-danger); }
.sw-agentic-dim--poor .sw-agentic-dim__state { color: var(--sw-poor-text); }

/* ── Zahlenzeile statt KPI-Kacheln (#849, Gründer-Entscheid zu Q12) ──
   Der Gründer hat Stat-Kacheln fürs Produkt abgelehnt: eine große zentrierte
   Zahl über einem Versallabel liest sich als Schlagzeile, obwohl sie eine
   Nebenangabe ist. Dieselben Zahlen stehen hier in einer ruhigen Zeile, Zahl
   und Wort zusammen. Der Admin behält seine Kacheln - siehe CLAUDE.md. */
.sw-figures {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem 1.75rem;
    margin: 0 0 2rem;
    font-size: var(--sw-text-md);
    color: var(--sw-text-secondary);
}
.sw-figures__item { display: inline-flex; align-items: baseline; gap: .375rem; }
.sw-figures__item .sw-badge { align-self: center; }
.sw-figures b { font-weight: 600; color: var(--sw-text); font-variant-numeric: tabular-nums; }
.sw-figures__own { color: var(--sw-brand-text); }
.sw-figures--hero { justify-content: center; margin: 2.5rem 0 0; color: rgba(255, 255, 255, .72); }
.sw-figures--hero b { color: #fff; }
/* ── Reputation: der Ausweg, wenn ein Anbieter meldet (FE-58) ──
   Die Liste sitzt im Meldungs-Baustein (.sw-notice), nicht in einer eigenen
   Karte: sie ist die Fortsetzung des Satzes darüber, nicht ein zweites Thema.
   Jeder Anbieter steht mit Namen da - ein zusammengefasstes Urteil wäre genau
   die Panik, die ein Fehlalarm nicht verdient. */
.sw-reputation-appeal__list {
    list-style: none;
    margin: .625rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .375rem;
    font-size: var(--sw-text-base);
}
.sw-reputation-appeal__list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; }
.sw-reputation-appeal__list a { font-weight: 600; color: var(--sw-brand-text); }
.sw-reputation-appeal__list span { color: var(--sw-text-secondary); }
.sw-reputation-appeal__note { margin: .75rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-reputation-disclaimer {
    margin: 1.25rem 0 0;
    font-size: var(--sw-text-sm);
    line-height: 1.6;
    color: var(--sw-text-muted);
}

/* ── Vorläufiger Score (#872) ──
   Solange PageSpeed für einen neuen Shop noch fehlt, zählt die Performance mit
   der Hälfte des Medians. Der Satz dazu steht direkt unter der Zahl, leise, aber
   lesbar: er ist der sichtbare Grund für jeden Punkt, der daraus fehlt. */
.sw-cmd-score-provisional,
.sw-first-score__note {
    margin: .5rem 0 0;
    font-size: var(--sw-text-sm);
    line-height: 1.5;
    color: var(--sw-text-secondary);
}

/* ── Vorläufiger Score auf der /try-Ergebnisseite (#897) ──
   Dieselbe Aussage wie im Dashboard, nur an der Stelle, an der ein anonymer
   Besucher die Zahl zum ersten Mal sieht: die Performance wird noch gemessen und
   zählt bis dahin mit der Hälfte des Medians. Leise unter der Zahl, damit sie den
   Moment nicht zerredet, aber sichtbar, weil jeder Punkt einen Grund braucht. */
.sw-result-panel__provisional {
    margin: .5rem 0 0;
    font-size: var(--sw-text-sm);
    line-height: 1.5;
    color: var(--sw-text-muted);
}

/* ── Nachweis-Spur und kopierfertige Zeile am Befund (FE-60) ──
   Zwei optionale Teile der geteilten Befund-Karte. Beide bleiben leise: die
   Karte führt weiter mit dem Rat, der Nachweis liegt zugeklappt darunter. Farben
   kommen ausschließlich aus Tokens, damit hell und dunkel ohne Sonderregel
   funktionieren. */
.sw-finding-snippet {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
    margin-top: .875rem;
    padding: .625rem .75rem;
    background: var(--sw-bg-subtle);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-inline);
}
.sw-finding-snippet__code {
    flex: 1 1 16rem;
    min-width: 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text);
    overflow-wrap: anywhere;
}
.sw-finding-snippet__copy {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .3rem .75rem;
    font-size: var(--sw-text-sm);
    font-weight: 550;
    color: var(--sw-text-secondary);
    background: var(--sw-surface);
    border: 1px solid var(--sw-border-strong);
    border-radius: var(--sw-radius-btn);
    cursor: pointer;
}
.sw-finding-snippet__copy:hover { color: var(--sw-text); }
.sw-finding-snippet__copy.is-copied { color: var(--sw-success-text); border-color: var(--sw-success); }
.sw-finding-snippet__copy svg { width: 15px; height: 15px; }

.sw-finding-evidence { margin-top: .875rem; }
.sw-finding-evidence__summary {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    font-size: var(--sw-text-sm);
    font-weight: 550;
    color: var(--sw-text-secondary);
    cursor: pointer;
    list-style: none;
}
/* #913: inline-flex drops the native disclosure triangle, so the summary read as
   plain text. An explicit chevron says "this opens" and turns when it is open. */
.sw-finding-evidence__summary::-webkit-details-marker { display: none; }
.sw-finding-evidence__summary::before {
    content: "";
    width: .45rem;
    height: .45rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform .15s ease;
}
.sw-finding-evidence[open] > .sw-finding-evidence__summary::before { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) {
    .sw-finding-evidence__summary::before { transition: none; }
}
.sw-finding-evidence__summary:hover { color: var(--sw-text); }
.sw-finding-evidence__list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .25rem .75rem;
    margin: .625rem 0 0;
    font-size: var(--sw-text-sm);
    color: var(--sw-text-secondary);
}
.sw-finding-evidence__list dt { font-weight: 550; color: var(--sw-text-muted); }
.sw-finding-evidence__list dd { margin: 0; overflow-wrap: anywhere; }
.sw-finding-evidence__list code { font-size: var(--sw-text-sm); color: var(--sw-text); }

@media (max-width: 575.98px) {
    .sw-finding-evidence__list { grid-template-columns: 1fr; gap: 0 0; }
    .sw-finding-evidence__list dd { margin-bottom: .375rem; }
}

/* ── DMEXCO stage (#939) ──
   A one-pager: no navigation, no footer, nothing to scroll to. The campaign
   page is a stage from the first second: big promise, a fact card that keeps
   turning with a bar to the next fact, and - once the scan runs - the countdown
   in the headline, the five rows and the score. Behind it a drifting field of
   points (canvas) on a dark ground with a brand glow and a touch of grain.
   Always dark, so the tokens are the dark ones on purpose. */
.sw-dmexco {
    --sw-brand-text: var(--sw-brand-light);
    --sw-brand-tint: rgba(59, 130, 246, 0.14);
    position: relative;
    isolation: isolate;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--sw-footer-bg);
    color: #fff;
}
.sw-dmexco::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse 60% 45% at 50% -5%, rgba(59, 130, 246, .30), transparent 70%),
        radial-gradient(ellipse 45% 40% at 85% 100%, rgba(29, 78, 216, .22), transparent 70%),
        radial-gradient(ellipse 80% 60% at 50% 60%, transparent 30%, rgba(8, 12, 22, .55) 100%);
}
.sw-dmexco::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: .055;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.sw-dmexco-bg { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.sw-dmexco > .sw-dmexco-top,
.sw-dmexco > .sw-dmexco-stage,
.sw-dmexco > .sw-dmexco-waitlist,
.sw-dmexco > .sw-dmexco-legal { position: relative; z-index: 1; }

/* Thin top line instead of the navigation: the mark, and the language. */
.sw-dmexco-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .875rem clamp(1rem, 3vw, 2rem) 0; }
.sw-dmexco-top .sw-navbar-brand { color: #fff; }
.sw-dmexco-top .sw-locale-switcher { position: static; margin: 0; }
/* The way back to the form, live only (#941). */
.sw-dmexco-back { display: inline-flex; align-items: center; gap: .4rem; margin-left: auto; margin-right: 1.25rem; padding: .35rem .85rem; border-radius: var(--sw-radius-btn); border: 1px solid rgba(255, 255, 255, .18); color: rgba(255, 255, 255, .8); font-size: var(--sw-text-sm); font-weight: 600; text-decoration: none; white-space: nowrap; }
.sw-dmexco-back:hover { color: #fff; border-color: rgba(255, 255, 255, .45); }

.sw-dmexco-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 1rem clamp(1rem, 3vw, 2rem) .75rem; }

.sw-dmexco-eyebrow { display: block; margin-bottom: .875rem; font-size: var(--sw-text-sm); }
.sw-dmexco-live { display: inline-flex; align-items: center; gap: .5rem; }
.sw-dmexco-live b { color: #fff; font-weight: 600; text-transform: none; letter-spacing: 0; }
.sw-dmexco-live__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--sw-success); animation: sw-dmexco-ping 1.6s ease-out infinite; }
.sw-dmexco.is-done .sw-dmexco-live__dot { animation: none; }
@keyframes sw-dmexco-ping {
    0%   { box-shadow: 0 0 0 0 rgba(34, 197, 94, .55); }
    100% { box-shadow: 0 0 0 12px rgba(34, 197, 94, 0); }
}

/* Bigger, on purpose: this headline is read from an arm's length on a phone.
   Capped by the viewport height too, so the page never has to scroll. */
.sw-dmexco h1.sw-dmexco-headline { font-size: clamp(2.5rem, min(5.6vw, 8vh), 5.25rem); font-weight: 700; line-height: 1.04; letter-spacing: -.03em; color: #fff; margin: 0 0 .875rem; outline: none; text-wrap: balance; }
.sw-dmexco-highlight { font-variant-numeric: tabular-nums; }
.sw-dmexco-highlight small { font-size: .42em; font-weight: 600; margin-left: .06em; }

/* The promised window as a line that drains; done, it fills and turns green. */
.sw-dmexco-track { width: min(640px, 100%); height: 5px; margin: -.125rem auto 1.25rem; border-radius: var(--sw-radius-btn); background: rgba(255, 255, 255, .12); overflow: hidden; }
.sw-dmexco-track__fill { display: block; height: 100%; width: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--sw-brand-light), var(--sw-brand)); }
.sw-dmexco-track--done .sw-dmexco-track__fill { width: 100% !important; transition: width .6s ease, background .6s ease !important; background: linear-gradient(90deg, var(--sw-brand), var(--sw-success)); }
.sw-dmexco-track--off .sw-dmexco-track__fill { transition: none !important; width: 0 !important; }

.sw-dmexco-sub { font-size: clamp(1.0625rem, 1.5vw, 1.3125rem); line-height: 1.45; color: var(--sw-dark-text-secondary); max-width: 860px; margin: 0 auto .75rem; }
.sw-dmexco-note { color: var(--sw-dark-text-secondary); font-size: var(--sw-text-md); line-height: 1.45; max-width: 860px; margin: 0 auto .75rem; }
.sw-dmexco-note__link { color: var(--sw-brand-light); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.sw-dmexco-note__link:hover, .sw-dmexco-note__link:focus-visible { color: #fff; }

/* The one action: wide field, big button. Leaves once the scan runs. */
.sw-dmexco-form { transition: opacity .28s ease, transform .28s ease; margin: .25rem 0 1.25rem; width: 100%; }
.sw-dmexco-form.is-leaving { opacity: 0; transform: translateY(-6px); pointer-events: none; }
.sw-dmexco-scan { max-width: 720px; margin: 0 auto; padding: 1.375rem 1.5rem; text-align: left; }
.sw-dmexco-scan .sw-form-label { font-size: var(--sw-text-lg); }
.sw-dmexco-scan .sw-form-control { font-size: var(--sw-text-xl); padding: .95rem 1.1rem; }
.sw-dmexco-scan .sw-btn-primary-lg { font-size: var(--sw-text-xl); padding: .95rem 1.75rem; }
.sw-dmexco-hint { max-width: 720px; margin: .875rem auto 0; font-size: var(--sw-text-md); }
.sw-dmexco-error { color: #FCA5A5; font-size: var(--sw-text-md); margin: .75rem 0 0; }

.sw-dmexco-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.25rem; width: min(1040px, 100%); margin: 0 auto; text-align: left; }
.sw-dmexco-col { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
/* Before the scan: facts beside the ranking; live: facts (and the QR) beside the rows. */
.sw-dmexco:not(.is-live) .sw-dmexco-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
.sw-dmexco.is-live .sw-dmexco-ranking { display: none; }

/* Ranking (#941): the shops analysed here most recently, best first. */
.sw-dmexco-ranking { display: flex; flex-direction: column; gap: .75rem; padding: 1.25rem 1.375rem 1rem; border-radius: var(--sw-radius-panel); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12); backdrop-filter: blur(6px); }
.sw-dmexco-ranking__head { display: flex; flex-direction: column; gap: .2rem; }
.sw-dmexco-ranking__sub { font-size: var(--sw-text-md); color: #fff; font-weight: 600; }
.sw-dmexco-ranking__empty { margin: auto 0; font-size: var(--sw-text-md); color: var(--sw-dark-text-secondary); line-height: 1.5; }
.sw-dmexco-ranking__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.sw-dmexco-ranking__row { display: flex; align-items: center; gap: .625rem; padding: .3rem .625rem; border-radius: var(--sw-radius-inline); font-size: var(--sw-text-md); color: #fff; }
/* Six rows fit beside the fact card without pushing the page past one screen. */
.sw-dmexco-ranking__row:nth-child(n+7) { display: none; }
.sw-dmexco-ranking__row.is-yours { background: rgba(59, 130, 246, .16); box-shadow: inset 0 0 0 1px rgba(147, 197, 253, .45); }
.sw-dmexco-ranking__pos { width: 1.25rem; font-variant-numeric: tabular-nums; font-size: var(--sw-text-xs); font-weight: 700; color: var(--sw-dark-text-secondary); text-align: right; flex-shrink: 0; }
.sw-dmexco-ranking__domain { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.sw-dmexco-ranking__domain em { font-style: normal; font-size: var(--sw-text-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--sw-brand-light); margin-left: .375rem; }
.sw-dmexco-ranking__score { font-variant-numeric: tabular-nums; font-weight: 700; font-size: var(--sw-text-lg); flex-shrink: 0; }
.sw-dmexco-ranking__score small { font-size: var(--sw-text-2xs); font-weight: 500; color: var(--sw-dark-text-secondary); margin-left: .05em; }
.sw-dmexco-ranking__score--good { color: #4ade80; }
.sw-dmexco-ranking__score--moderate { color: #fbbf24; }
.sw-dmexco-ranking__score--poor { color: #f87171; }

/* The try on the visitor's phone (#941): a QR code under the facts, desktop only. */
.sw-dmexco-qr { display: flex; align-items: center; gap: 1rem; padding: .75rem .875rem; border-radius: var(--sw-radius-panel); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12); }
.sw-dmexco-qr img { display: block; width: 112px; height: 112px; flex-shrink: 0; border-radius: var(--sw-radius-inline); background: #fff; }
.sw-dmexco-qr__text { display: flex; flex-direction: column; gap: .25rem; }
.sw-dmexco-qr__text strong { color: #fff; font-size: var(--sw-text-lg); }
.sw-dmexco-qr__text span { color: var(--sw-dark-text-secondary); font-size: var(--sw-text-base); line-height: 1.45; }
.sw-dmexco.is-mail-open .sw-dmexco-qr { display: none; }

/* Fact card: label, one big sentence, source, dots and the bar to the next fact. */
.sw-dmexco-facts { position: relative; display: flex; flex-direction: column; gap: 1rem; padding: 1.375rem 1.75rem 1.25rem; border-radius: var(--sw-radius-panel); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12); backdrop-filter: blur(6px); min-height: 210px; }
.sw-dmexco-facts__head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
.sw-dmexco-facts__pause { min-height: 36px; background: none; border: 1px solid rgba(255, 255, 255, .2); color: rgba(255, 255, 255, .8); border-radius: var(--sw-radius-btn); font: inherit; font-size: var(--sw-text-sm); line-height: 1.4; padding: .2rem .75rem; cursor: pointer; }
.sw-dmexco-facts__pause:hover,
.sw-dmexco-facts__pause:focus-visible { color: #fff; border-color: rgba(255, 255, 255, .5); outline: none; }
/* The sentence sits mid-card like a slide, whatever height the rows beside it reach. */
.sw-dmexco-facts__body { margin: auto 0; transition: opacity .24s ease, transform .24s ease; }
.sw-dmexco-facts__body.is-swapping { opacity: 0; transform: translateY(8px); }
.sw-dmexco-facts__text { margin: 0; font-size: clamp(1.25rem, min(2.2vw, 3.2vh), 1.75rem); line-height: 1.35; font-weight: 600; letter-spacing: -.01em; color: #fff; text-wrap: pretty; }
.sw-dmexco-facts__source { margin: .625rem 0 0; font-size: var(--sw-text-md); color: var(--sw-dark-text-secondary); }
.sw-dmexco-facts__foot { display: flex; flex-direction: column; gap: .75rem; }
.sw-dmexco-facts__dots { display: flex; flex-wrap: wrap; gap: .4rem; }
.sw-dmexco-facts__dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(255, 255, 255, .18); transition: background .2s ease, transform .2s ease; }
.sw-dmexco-facts__dots i.is-active { background: var(--sw-brand-light); transform: scale(1.3); }
/* The bar to the next fact: one linear run per fact, frozen while held or paused. */
.sw-dmexco-facts__bar { height: 4px; border-radius: var(--sw-radius-btn); background: rgba(255, 255, 255, .1); overflow: hidden; }
.sw-dmexco-facts__bar-fill { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--sw-brand), var(--sw-brand-light)); animation: sw-dmexco-fact-bar var(--fact-ms, 8s) linear forwards; }
.sw-dmexco-facts.is-held .sw-dmexco-facts__bar-fill { animation-play-state: paused; }
.sw-dmexco-facts.is-done .sw-dmexco-facts__bar { visibility: hidden; }
@keyframes sw-dmexco-fact-bar { from { width: 0; } to { width: 100%; } }

/* The five rows in the results page's look, a touch larger; its local tokens are set here. */
.sw-dmexco-panel { display: flex; flex-direction: column; gap: 10px; }
.sw-dmexco-panel .sw-result-panel__check { background: rgba(255, 255, 255, .05); backdrop-filter: blur(6px); padding: 11px 16px; gap: 14px; }
.sw-dmexco-panel .sw-result-panel__check-ic { width: 36px; height: 36px; border-radius: var(--sw-radius-inline); }
.sw-dmexco-panel .sw-result-panel__check-ic svg { width: 18px; height: 18px; }
.sw-dmexco-panel .sw-result-panel__check-name { font-size: var(--sw-text-md); }
.sw-dmexco-panel .sw-result-panel__cnt { font-size: var(--sw-text-xs); padding: 2px 9px; }
.sw-dmexco-panel .sw-result-panel__check-desc { font-size: var(--sw-text-sm); }

/* ── DMEXCO stage: a category opens and shows its findings (#994) ── */
.sw-dmexco-cat { display: flex; flex-direction: column; }
.sw-dmexco-cat.is-open .sw-result-panel__check { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.sw-dmexco-cat__toggle {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-control);
    color: var(--sw-text-secondary);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease, transform .2s ease;
}
.sw-dmexco-cat__toggle svg { width: 16px; height: 16px; }
/* Keeps its place while there is nothing to open, so the traffic lights of all
   categories stay in one column and no row jumps when its value lands. */
.sw-dmexco-cat__toggle[hidden] { display: flex; visibility: hidden; }
.sw-dmexco-cat__toggle:hover { color: var(--sw-text); border-color: var(--sw-border-strong); }
.sw-dmexco-cat__toggle:focus-visible { outline: 2px solid var(--sw-brand-light); outline-offset: 2px; }
.sw-dmexco-cat.is-open .sw-dmexco-cat__toggle { transform: rotate(180deg); color: var(--sw-brand-text); }
.sw-dmexco-cat__details {
    background: rgba(255, 255, 255, .03);
    border: 1px solid rgba(143, 163, 187, .12);
    border-top: 0;
    border-bottom-left-radius: var(--sw-radius-inline);
    border-bottom-right-radius: var(--sw-radius-inline);
    padding: 10px 16px 12px;
}
.sw-dmexco-cat__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.sw-dmexco-cat__finding {
    position: relative;
    padding-left: 18px;
    font-size: var(--sw-text-sm);
    line-height: 1.45;
    color: var(--sw-text-secondary);
}
.sw-dmexco-cat__finding::before {
    content: "";
    position: absolute;
    left: 2px;
    top: .5em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--sw-text-muted);
}
.sw-dmexco-cat__finding--error::before { background: var(--sw-danger); }
.sw-dmexco-cat__finding--warning::before { background: #f59e0b; }
.sw-dmexco-cat__finding--info::before { background: var(--sw-brand); }
.sw-dmexco-cat__times {
    display: inline-block;
    margin-left: 4px;
    padding: 1px 5px;
    border-radius: var(--sw-radius-xs);
    background: rgba(143, 163, 187, .14);
    font-size: var(--sw-text-2xs);
    font-variant-numeric: tabular-nums;
    color: var(--sw-text-muted);
}
.sw-dmexco-cat__more { margin: 9px 0 0; font-size: var(--sw-text-xs); color: var(--sw-text-muted); }

@media (max-width: 767.98px) {
    .sw-dmexco-cat__details { padding: 9px 13px 11px; }
}
.sw-dmexco-panel .sw-result-panel__answerable { color: var(--sw-dark-text-secondary); font-size: var(--sw-text-base); }
.sw-dmexco-panel .sw-result-panel__answerable--ok { color: var(--sw-success-text); }
/* The row whose turn it is (#941): a brand ring, a light sweeping through, the caption says so. */
.sw-dmexco-panel .sw-result-panel__check { position: relative; overflow: hidden; }
.sw-dmexco-panel .sw-result-panel__check.is-active { border-color: rgba(96, 165, 250, .75); background: rgba(59, 130, 246, .10); box-shadow: 0 0 0 3px rgba(59, 130, 246, .16), 0 8px 30px rgba(59, 130, 246, .22); }
.sw-dmexco-panel .sw-result-panel__check.is-active::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, transparent 20%, rgba(147, 197, 253, .16) 50%, transparent 80%); transform: translateX(-100%); animation: sw-dmexco-sweep 1.7s ease-in-out infinite; }
.sw-dmexco-panel .sw-result-panel__check.is-active .sw-result-panel__check-desc { color: var(--sw-brand-light); }
.sw-dmexco-panel .sw-result-panel__check.is-active .sw-result-panel__check-ic { background: rgba(59, 130, 246, .28); color: #fff; }
.sw-dmexco-panel .sw-result-panel__check.is-active .sw-result-panel__spinner { border-top-color: #fff; border-color: rgba(147, 197, 253, .45); border-top-color: #fff; }
.sw-dmexco-panel .sw-result-panel__check:not(.is-active):not(.is-filled) .sw-result-panel__spinner { animation: none; border-top-color: rgba(143, 163, 187, .5); }
@keyframes sw-dmexco-sweep { to { transform: translateX(100%); } }
/* The rows arrive one after another when the stage goes live. */
.sw-dmexco.is-live .sw-dmexco-panel .sw-result-panel__check { animation: sw-dmexco-row-in .45s cubic-bezier(.2, .7, .3, 1) both; animation-delay: calc(var(--i, 0) * 90ms + 120ms); }
@keyframes sw-dmexco-row-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.sw-dmexco-finish { display: flex; flex-direction: column; align-items: center; gap: .875rem; width: min(760px, 100%); margin: 1.125rem auto 0; opacity: 0; transform: translateY(6px); transition: opacity .4s ease, transform .4s ease; }
.sw-dmexco-finish.is-visible { opacity: 1; transform: none; }
.sw-dmexco-finish__row { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; }
/* #942: once the stage is live the rows carry it - the facts card steps back a
   little, so the scored, walled and settled states keep one screen on a desktop. */
@media (min-width: 768px) {
    .sw-dmexco.is-live .sw-dmexco-facts { padding: 1.125rem 1.5rem 1rem; gap: .75rem; }
    .sw-dmexco.is-live .sw-dmexco-facts__text { font-size: clamp(1.125rem, min(1.8vw, 2.6vh), 1.5rem); }
    .sw-dmexco.is-live .sw-dmexco-panel .sw-result-panel__check { padding: 10px 16px; }
    .sw-dmexco.is-live .sw-dmexco-track { margin-bottom: 1rem; }
    .sw-dmexco.is-live .sw-dmexco-finish { margin-top: .875rem; }
    .sw-dmexco.is-live .sw-dmexco-legal { padding-top: .5rem; padding-bottom: .5rem; }
    /* Nothing to take along when the shop never answered: the QR card leaves, the state keeps one screen. */
    .sw-dmexco.is-ended--unreachable .sw-dmexco-qr { display: none; }
    .sw-dmexco.is-ended .sw-dmexco-note { margin-bottom: .5rem; }
    .sw-dmexco.is-ended .sw-dmexco-finish { margin-top: .625rem; }
}
.sw-dmexco-finish .sw-btn-outline { color: #fff !important; border-color: rgba(255, 255, 255, .3); }
.sw-dmexco-finish .sw-btn-outline:hover { background: rgba(255, 255, 255, .08); }

/* The result by mail (#941): sits where the QR code was while open. */
.sw-dmexco-mail { padding: .75rem .875rem; border-radius: var(--sw-radius-panel); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12); text-align: left; }
.sw-dmexco-mail__head { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; margin-bottom: .5rem; }
.sw-dmexco-mail__title { margin: 0; font-weight: 700; font-size: var(--sw-text-md); color: #fff; }
.sw-dmexco-mail__sub { margin: .125rem 0 0; font-size: var(--sw-text-sm); line-height: 1.4; color: var(--sw-dark-text-secondary); }
.sw-dmexco-mail__close { flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .18); background: none; color: rgba(255, 255, 255, .75); font-size: var(--sw-text-2xl); line-height: 1; cursor: pointer; }
.sw-dmexco-mail__close:hover, .sw-dmexco-mail__close:focus-visible { color: #fff; border-color: rgba(255, 255, 255, .45); outline: none; }
.sw-dmexco-mail__form { display: flex; gap: .5rem; }
.sw-dmexco-mail__form .sw-form-control { flex: 1; min-width: 0; }
.sw-dmexco-mail__form .sw-btn { flex-shrink: 0; }
.sw-dmexco-mail__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.sw-dmexco-mail__status { margin: .5rem 0 0; font-size: var(--sw-text-base); color: #fff; }
.sw-dmexco-mail__form .sw-form-control { padding: .6rem .8rem; }

/* The legal links every page needs, quietly at the bottom. */
.sw-dmexco-legal { display: flex; justify-content: center; gap: 1.25rem; margin: 0; padding: .375rem 1rem .75rem; font-size: var(--sw-text-sm); }
.sw-dmexco-legal a { color: rgba(255, 255, 255, .5); text-decoration: none; }
.sw-dmexco-legal a:hover { color: #fff; }

/* The waitlist under the homepage stage (#1127): one quiet band, one field, one button. */
.sw-dmexco-waitlist { width: min(720px, 100%); margin: 0 auto; padding: 2rem clamp(1rem, 3vw, 2rem) 1.5rem; text-align: center; scroll-margin-top: 1rem; }
.sw-dmexco-waitlist__title { margin: 0 0 .5rem; font-size: var(--sw-text-3xl); font-weight: 700; letter-spacing: -.02em; color: #fff; }
.sw-dmexco-waitlist__sub { margin: 0 0 1rem; font-size: var(--sw-text-lg); line-height: 1.5; color: var(--sw-dark-text-secondary); }
.sw-dmexco-waitlist__form { text-align: left; }
.sw-dmexco-waitlist__field { flex: 1; min-width: 0; }
.sw-dmexco-waitlist__note { margin: .75rem 0 0; text-align: center; font-size: var(--sw-text-sm); color: var(--sw-dark-text-secondary); }
.sw-dmexco-waitlist__done { margin: 0; padding: 1rem 1.25rem; border-radius: var(--sw-radius-panel); background: rgba(34, 197, 94, .12); color: #fff; font-size: var(--sw-text-lg); line-height: 1.5; }
.sw-dmexco-waitlist .sw-dmexco-error { margin: .5rem 0 0; }
.sw-dmexco-waitlist .sw-dmexco-error:empty { display: none; }
.sw-dmexco-waitlist .sw-dmexco-error ul { margin: 0; padding: 0; list-style: none; }
.sw-dmexco-waitlist__hp { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 767.98px) {
    .sw-dmexco-waitlist { padding: 1.5rem 1rem 1rem; }
    .sw-dmexco-waitlist__title { font-size: var(--sw-text-2xl); }
    .sw-dmexco-waitlist__sub { font-size: var(--sw-text-md); }
    .sw-dmexco-waitlist .sw-home-scan-row { flex-direction: column; }
    .sw-dmexco-waitlist .sw-btn { width: 100%; }
}

/* A phone shows the whole stage without scrolling. Before the scan: the promise,
   the field, the fact card. Live: the rows go to one line and the card gives up
   its height. Scored: the card makes room for the two buttons. */
@media (max-width: 767.98px) {
    .sw-dmexco-top { padding-top: .75rem; }
    .sw-dmexco-stage { padding: .75rem 1rem .5rem; }
    .sw-dmexco-eyebrow { margin-bottom: .5rem; font-size: var(--sw-text-xs); }
    .sw-dmexco h1.sw-dmexco-headline { font-size: clamp(2rem, 10vw, 2.5rem); margin-bottom: .625rem; }
    .sw-dmexco-sub { font-size: var(--sw-text-md); line-height: 1.4; margin-bottom: .625rem; }
    .sw-dmexco-note { font-size: var(--sw-text-sm); line-height: 1.4; margin-bottom: .625rem; }
    .sw-dmexco-hint { display: none; }
    .sw-dmexco-form { margin: 0 0 .875rem; }
    .sw-dmexco-scan { padding: .875rem; }
    .sw-dmexco-scan .sw-form-label { font-size: var(--sw-text-base); margin-bottom: .25rem; }
    .sw-dmexco-scan .sw-form-control { font-size: var(--sw-text-lg); padding: .75rem .9rem; }
    .sw-dmexco-scan .sw-btn-primary-lg { font-size: var(--sw-text-lg); padding: .75rem 1.25rem; }
    .sw-dmexco-grid, .sw-dmexco:not(.is-live) .sw-dmexco-grid { grid-template-columns: 1fr; gap: .625rem; } /* #953 P-02: same specificity as the intro's two columns */
    .sw-dmexco-facts { min-height: 0; padding: .875rem 1rem .75rem; gap: .5rem; border-radius: var(--sw-radius-panel); }
    .sw-dmexco-facts__text { font-size: var(--sw-text-xl); line-height: 1.35; }
    .sw-dmexco-facts__source { font-size: var(--sw-text-sm); margin-top: .375rem; }
    .sw-dmexco-facts__dots { display: none; }
    .sw-dmexco-facts__foot { gap: 0; }
    .sw-dmexco-track { margin-bottom: .625rem; }
    .sw-dmexco.is-live .sw-dmexco-facts__text { font-size: var(--sw-text-lg); }
    .sw-dmexco.is-live .sw-dmexco-facts__source { font-size: var(--sw-text-xs); margin-top: .25rem; }
    .sw-dmexco.is-scored .sw-dmexco-facts { display: none; }
    .sw-dmexco-panel { gap: 6px; }
    .sw-dmexco-panel .sw-result-panel__check { padding: 6px 10px; gap: 10px; border-radius: var(--sw-radius-inline); }
    .sw-dmexco-panel .sw-result-panel__check-ic { width: 26px; height: 26px; border-radius: var(--sw-radius-control); }
    .sw-dmexco-panel .sw-result-panel__check-ic svg { width: 14px; height: 14px; }
    .sw-dmexco-panel .sw-result-panel__check-name { font-size: var(--sw-text-base); }
    .sw-dmexco-panel .sw-result-panel__cnt { font-size: var(--sw-text-2xs); }
    .sw-dmexco-panel .sw-result-panel__check-desc { display: none; }
    .sw-dmexco-panel .sw-result-panel__answerable { display: none; }
    .sw-dmexco-finish { margin-top: .5rem; gap: .375rem; width: 100%; }
    .sw-dmexco-finish__row { flex-wrap: wrap; gap: .5rem; width: 100%; }
    .sw-dmexco-finish .sw-btn { flex: 1 1 40%; justify-content: center; padding: .65rem .5rem; font-size: var(--sw-text-base); white-space: nowrap; }
    /* The third way is a plain link on a phone: two buttons fill the row, a third would need one of its own. */
    .sw-dmexco-finish [data-dmexco-stage-target="mailToggle"] { flex-basis: 100%; background: none !important; border: 0 !important; padding: .2rem !important; font-size: var(--sw-text-base); color: var(--sw-brand-light) !important; text-decoration: underline; text-underline-offset: 3px; }
    .sw-dmexco-qr { display: none; }
    /* The column dissolves so the mail form can sit under the rows, right above the buttons it replaces. */
    .sw-dmexco-col { display: contents; }
    .sw-dmexco-panel { order: 1; }
    .sw-dmexco-mail { order: 2; }
    .sw-dmexco.is-mail-open .sw-dmexco-finish__row,
    .sw-dmexco.is-mail-open .sw-dmexco-sub,
    .sw-dmexco.is-mail-open .sw-dmexco-note { display: none; }
    .sw-dmexco-top { padding-top: .5rem; }
    .sw-dmexco-back { margin-right: 0; padding: .2rem .6rem; font-size: var(--sw-text-xs); }
    /* The top line keeps its 16px gutter on a phone (#1142): the touch padding of the
       language links (12px a side from the global 44px target rule) used to push "EN"
       out past the edge next to "Neue Analyse". Less padding, and the last link hangs
       into the gutter so its letters line up with the mark on the left. */
    .sw-dmexco-top { gap: .75rem; }
    .sw-dmexco-top .sw-locale-link { padding: 0 .5rem; }
    .sw-dmexco-top .sw-locale-switcher { margin-right: -.5rem; }
    .sw-dmexco-legal { padding: .125rem 1rem .4rem; }
    .sw-dmexco-ranking { padding: .875rem 1rem .75rem; gap: .5rem; }
    .sw-dmexco-ranking__row { font-size: var(--sw-text-base); padding: .25rem .5rem; }
    .sw-dmexco-ranking__row:nth-child(n+6) { display: none; }
    .sw-dmexco-mail { padding: .875rem; }
    .sw-dmexco-mail__form { flex-direction: column; }
    .sw-dmexco-legal { padding: .25rem 1rem .5rem; font-size: var(--sw-text-xs); }
}
/* The narrowest phones: the arrow of the way back gives way so the three still fit (#1142). */
@media (max-width: 380px) {
    .sw-dmexco-top { gap: .5rem; }
    .sw-dmexco-back svg { display: none; }
}
@media (max-width: 340px) {
    .sw-dmexco-top .sw-navbar-brand { font-size: var(--sw-text-xl); gap: .375rem; }
    .sw-dmexco-top .sw-navbar-logo { width: 22px; height: 22px; }
    .sw-dmexco-back { padding: .2rem .5rem; }
}
/* A short phone (a browser with its bars open): the greeting steps aside before
   the scan, the promise and the field are what matter there. */
@media (max-width: 767.98px) and (max-height: 720px) {
    .sw-dmexco:not(.is-live) .sw-dmexco-sub { display: none; }
    .sw-dmexco:not(.is-live) .sw-dmexco-eyebrow { display: none; }
    .sw-dmexco-ranking { display: none; }
    .sw-dmexco-form { margin-bottom: .5rem; }
    .sw-dmexco-facts__text { font-size: var(--sw-text-lg); }
    .sw-dmexco.is-live .sw-dmexco-track { margin-bottom: .375rem; }
    .sw-dmexco.is-live .sw-dmexco-sub,
    .sw-dmexco.is-live .sw-dmexco-note { margin-bottom: .375rem; }
    .sw-dmexco.is-live .sw-dmexco-finish { margin-top: .25rem; }
    .sw-dmexco h1.sw-dmexco-headline { margin-bottom: .5rem; }
    .sw-dmexco-facts { padding: .75rem .875rem .625rem; }
    .sw-dmexco-scan { padding: .75rem; }
    .sw-dmexco-scan .sw-url-status { min-height: 1rem; margin-top: .25rem; }
    .sw-dmexco.is-live .sw-dmexco-sub { font-size: var(--sw-text-base); }
    .sw-dmexco.is-live .sw-dmexco-note { font-size: var(--sw-text-xs); }
    /* While the countdown runs the headline says it all; the verdict and the honest states keep their line. */
    .sw-dmexco.is-live:not(.is-scored):not(.is-done) .sw-dmexco-sub { display: none; }
    /* With the result in the headline the eyebrow's "live" and the domain have done their job (#942). */
    .sw-dmexco.is-scored .sw-dmexco-eyebrow { display: none; }
}
/* An end without a score on a phone (#942): the headline and the note say it all -
   the facts have stopped, and five rows repeating "could not be measured" would
   only push the way out below the fold. Rows with values (a timeout, no score
   after a full run) stay. */
@media (max-width: 767.98px) {
    .sw-dmexco.is-done .sw-dmexco-facts { display: none; }
    .sw-dmexco.is-ended--unreachable .sw-dmexco-panel,
    .sw-dmexco.is-ended--wall .sw-dmexco-panel { display: none; }
}
/* A short desktop window (a laptop with the bar open) keeps everything on one screen too. */
@media (min-width: 768px) and (max-height: 820px) {
    .sw-dmexco h1.sw-dmexco-headline { font-size: clamp(2.25rem, 6vh, 3.75rem); margin-bottom: .625rem; }
    .sw-dmexco-sub { font-size: var(--sw-text-xl); }
    .sw-dmexco-facts { min-height: 190px; padding: 1.125rem 1.375rem 1rem; }
    .sw-dmexco-facts__text { font-size: var(--sw-text-2xl); }
    .sw-dmexco.is-live .sw-dmexco-panel .sw-result-panel__check { padding: 8px 14px; }
    .sw-dmexco.is-live .sw-dmexco-sub, .sw-dmexco.is-live .sw-dmexco-note { margin-bottom: .5rem; }
    .sw-dmexco-form { margin: .25rem 0 1rem; }
    .sw-dmexco-scan { padding: 1rem 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
    .sw-dmexco-live__dot { animation: none; }
    .sw-dmexco-form, .sw-dmexco-facts__body, .sw-dmexco-finish, .sw-dmexco-track__fill { transition: none !important; }
    .sw-dmexco.is-live .sw-dmexco-panel .sw-result-panel__check { animation: none; }
    .sw-dmexco-panel .sw-result-panel__check.is-active::after { animation: none; }
    .sw-dmexco-facts__bar { display: none; }
}

/* #920 (F-03): an e-mail address in running text wraps at "@" only. Each half
   moves as one box; only a half wider than the column breaks inside itself. */
.sw-email-break > span { display: inline-block; max-width: 100%; overflow-wrap: anywhere; }

/* ── #955 account UX batch ── */
/* A-17: the score panel keeps its own height instead of stretching to the trend chart. */
.sw-cmd-score-panel { align-self: start; }
/* A-15: the history gate's one CTA lives in the placeholder card. */

/* A-20: the weekly bar's hint shows only where the weekly bar does (phones). */
.sw-uptime-bar-weeks-hint { display: none; margin: .5rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); line-height: 1.45; }
@media (max-width: 767.98px) { .sw-uptime-bar-weeks-hint { display: block; } }
/* A-22: on a phone the impact chip may wrap - as a soft tag, not a broken pill. */
@media (max-width: 575.98px) {
    .sw-nba__impact-badge { white-space: normal; border-radius: var(--sw-radius-card); line-height: 1.35; text-align: left; }
}
/* A-13: the action plan's tail - folded by report, one line per action. */
/* History day delta: green fixed, red came-back, amber new. A zero stays muted,
   so the line reads as "what moved" instead of three equal numbers. The word
   next to each figure carries the meaning; colour only speeds up the scan. */
.sw-history-delta { display:inline-flex; flex-wrap:wrap; align-items:center; gap:.4rem; }
.sw-history-delta__part { color:var(--sw-text-muted); }
.sw-history-delta__part--fixed { color:var(--sw-success-text); font-weight:600; }
.sw-history-delta__part--regressed { color:var(--sw-poor-text); font-weight:600; }
.sw-history-delta__part--new { color:var(--sw-warning-text); font-weight:600; }
.sw-history-delta__sep { color:var(--sw-text-muted); opacity:.6; }

/* Same rail as .sw-nba-step, so the folded rest lines up with the cards
   instead of with the step numbers (UI-Durchgang 2026-09-28). */
/* No step rail since the focus layout (#1031): the groups run full width. */
.sw-nba__more { width: 100%; margin-top: 1.75rem; display: flex; flex-direction: column; gap: .625rem; }
.sw-nba__more-lead { margin: 0 0 .25rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); }
.sw-nba__group { background: var(--sw-bg); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-card); }
.sw-nba__group-summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .75rem; padding: .875rem 1.125rem; font-weight: 600; font-size: var(--sw-text-md); }
.sw-nba__group-summary::-webkit-details-marker { display: none; }
.sw-nba__group-count { margin-left: auto; font-size: var(--sw-text-sm); font-weight: 500; color: var(--sw-text-secondary); white-space: nowrap; }
.sw-nba__group-chevron { width: 16px; height: 16px; flex-shrink: 0; color: var(--sw-text-muted); transition: transform .2s ease; }
.sw-nba__group[open] .sw-nba__group-chevron { transform: rotate(90deg); }
.sw-nba__group-list { list-style: none; margin: 0; padding: 0 1.125rem .5rem; }
.sw-nba__group-item { display: grid; grid-template-columns: 1fr auto; gap: .125rem .75rem; padding: .625rem 0; border-top: 1px solid var(--sw-border); align-items: center; }
.sw-nba__group-message { font-size: var(--sw-text-md); color: var(--sw-text); }
.sw-nba__group-meta { grid-column: 1; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-nba__group-item .sw-nba__item-link { grid-column: 2; grid-row: 1 / span 2; }
@media (max-width: 575.98px) {
    .sw-nba__group-item { grid-template-columns: 1fr; }
    .sw-nba__group-item .sw-nba__item-link { grid-column: 1; grid-row: auto; }
}
/* A-24: history days after the second fold into a summary line. */
.sw-history-feed-day__summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .5rem; font-size: var(--sw-text-base); color: var(--sw-text-secondary); margin: .25rem 0 .5rem; }
.sw-history-feed-day__summary::-webkit-details-marker { display: none; }
.sw-history-feed-day__chevron { width: 14px; height: 14px; flex-shrink: 0; transition: transform .2s ease; }
.sw-history-feed-day__details[open] .sw-history-feed-day__chevron { transform: rotate(90deg); }

/* Shop detail: the five category figures in one quiet line (#957 S-3, D-07 - the
   KPI tiles were the pattern the founder rejected everywhere but the admin). */
.sw-cmd-kpis { margin-bottom: 1.5rem; }
.sw-cmd-kpi { color: inherit; text-decoration: none; }
.sw-cmd-kpi:hover { text-decoration: none; color: inherit; }
.sw-cmd-kpi:hover b { color: var(--sw-brand-text); }
.sw-cmd-kpi__unit { color: var(--sw-text-muted); }
.sw-cmd-kpi__pending { color: var(--sw-text-secondary); font-weight: 500; }
.sw-cmd-kpi__tag { margin-left: .125rem; }

/* ── Analytics area page ── */
.sw-av2-section__verdict { justify-content: space-between; flex-wrap: wrap; row-gap: .5rem; }
.sw-av2-area-more { margin: 2rem 0 0; }
/* S-2 (2026-09-29): the section is one framed block - the head is its top edge
   (it had no side border, so the first row's rounded corners sat under a flat
   bar), the last element its rounded bottom. */
.sw-av2-section > .sw-cmd-cat-header {
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-card) var(--sw-radius-card) 0 0;
}
.sw-av2-section > .sw-cmd-cat-header + .sw-av2-rows > .sw-av2-row:first-child { border-top: none; border-radius: 0; }
.sw-av2-section > .sw-av2-rows:last-child > .sw-av2-row:last-child,
.sw-av2-section > .sw-av2-all-clear:last-child,
.sw-av2-section > .sw-av2-more:last-child {
    border-bottom-left-radius: var(--sw-radius-card);
    border-bottom-right-radius: var(--sw-radius-card);
}

/* Dashboard shop tiles and rows carry the shop's icon tile (2026-09-29), like
   the shop list, competitors and tech stack; the light moved to the score. */
.sw-tile__id { display: inline-flex; align-items: center; gap: .625rem; min-width: 0; }
.sw-dash3-table__score { white-space: nowrap; }
.sw-nba__advice-more { margin: 0; }
.sw-nba__advice-more-toggle {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    cursor: pointer;
    list-style: none;
    color: var(--sw-brand-light);
    font-weight: 650;
    font-size: var(--sw-text-sm);
    text-transform: uppercase;
    letter-spacing: .04em;
}
.sw-nba__advice-more-toggle::-webkit-details-marker { display: none; }
.sw-nba__advice-more-toggle svg { width: 12px; height: 12px; transition: transform .15s; }
.sw-nba__advice-more[open] .sw-nba__advice-more-toggle svg { transform: rotate(90deg); }
.sw-nba__advice-more-toggle:focus-visible { outline: 2px solid var(--sw-brand); outline-offset: 2px; border-radius: var(--sw-radius-xs); }
.sw-nba__advice-more .sw-nba__advice-row { margin-top: .375rem; }
@media (prefers-reduced-motion: reduce) { .sw-nba__advice-more-toggle svg { transition: none; } }

.sw-uptime-main { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
.sw-uptime-main > .sw-card { height: auto; }
.sw-uptime-main > .sw-uptime-incidents-card { margin-top: 0; }

/* Account deletion: cards stacked with air between them, not flush (2026-09-29). */
.sw-delete .sw-card + .sw-card { margin-top: 1rem; }

/* ═════════════════════════════════════════════════════════════════════
   One panel style (founder 2026-09-29: analytics and uptime looked like two
   products). Every framed block on an account page is the same panel:
   --sw-surface, the quiet --sw-border hairline, the card radius, compact
   padding. Inner strips and headers use --sw-bg-subtle. The bright
   --sw-border-strong outline and the 2rem padding of the marketing card are
   not used inside the app any more, and the score panel's glass gradient
   is gone - one surface, everywhere.
   ═════════════════════════════════════════════════════════════════════ */
.sw-app-layout .sw-card {
    border-color: var(--sw-border);
}
.sw-app-layout .sw-card:not(.sw-md-background) { padding: var(--sw-card-pad-md); }
html.sw-dark .sw-cmd-score-panel,
.sw-cmd-score-panel,
.sw-cmd-trend-panel,
.sw-av2-top-action,
.sw-cmd-uptime,
.sw-av2-card,
.sw-subscore-card,
.sw-av2-row,
.sw-av2-all-clear {
    background: var(--sw-surface);
    border-color: var(--sw-border);
}
.sw-cmd-score-panel,
.sw-cmd-trend-panel { padding: var(--sw-card-pad-md); }
/* One card title: 16 px, semibold - the trend title, the uptime panel titles
   and the generic card title all read at the same size. */
.sw-app-layout .sw-card-title,
.sw-cmd-trend-title,
.sw-uptime-history-title {
    font-size: var(--sw-text-lg);
    font-weight: 600;
    letter-spacing: -.01em;
}
.sw-app-layout .sw-card-title { margin-bottom: .75rem; }
.sw-av2-pages { margin-top: .5rem; }
.sw-av2-pages .sw-md-section-head { margin: 1.25rem 0 .875rem; }
.sw-uptime-side-stat-row { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; justify-content: flex-start; }
.sw-uptime-side-stat-label { margin: 0; }
.sw-uptime-side-context__band { margin-top: .75rem; }
.sw-uptime-side-context { margin-top: .5rem; }
.sw-ts-category { background: var(--sw-surface); }
.sw-uptime-faq { margin: 1.5rem 0; }

/* The change icons (#1037): same marks as the dashboard's "since last week",
   and one colour per change everywhere - fixed green, new yellow, came back red. */
.sw-change-icon { width: 13px; height: 13px; flex-shrink: 0; vertical-align: -2px; margin-right: .25rem; }
.sw-coach__pchip .sw-change-icon { margin-right: .3rem; }
.sw-history-delta__part { display: inline-flex; align-items: center; }

/* ── NBA focus layout (founder pick 2026-09-29, #1031) ── */
/* The 820 px reading column suited one card list; the focus layout has two columns. */
.sw-nba--focus { max-width: none; gap: 0; }
.sw-nba-gain { font-size: var(--sw-text-sm); font-weight: 700; color: var(--sw-success-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sw-nba-focus-top { display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr); gap: 1.25rem; align-items: start; }
@media (max-width: 1099.98px) { .sw-nba-focus-top { grid-template-columns: minmax(0, 1fr); } }
.sw-nba-focus.sw-card, .sw-nba-side.sw-card, .sw-nba-tile.sw-card { height: auto; }
.sw-nba-focus.sw-card:hover, .sw-nba-side.sw-card:hover, .sw-nba-tile.sw-card:hover { transform: none; }
.sw-nba-focus__eyebrow { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; margin: 0 0 .875rem; }
.sw-nba-focus__cat { font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-nba-focus__title { font-size: var(--sw-text-2xl); font-weight: 700; line-height: 1.35; letter-spacing: -.01em; margin: 0 0 1rem; text-wrap: balance; }
.sw-nba-focus .sw-nba__advice { max-width: 68ch; margin-bottom: 0; }
.sw-nba-focus__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.25rem; }
.sw-nba-focus__foot { margin: 1rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-muted); }
.sw-nba-focus-side { display: flex; flex-direction: column; gap: 1rem; }
.sw-nba-side.sw-card { padding: var(--sw-card-pad-md); }
.sw-nba-side__title { font-size: var(--sw-text-lg); font-weight: 600; margin: 0 0 .5rem; }
.sw-nba-side__line { display: flex; justify-content: space-between; gap: 1rem; margin: 0; padding: .5rem 0; border-top: 1px solid var(--sw-border); font-size: var(--sw-text-base); }
.sw-nba-side__title + .sw-nba-side__line { border-top: 0; }
.sw-nba-side__line span { color: var(--sw-text-secondary); }
.sw-nba-side__line b { font-variant-numeric: tabular-nums; color: var(--sw-text); }
/* The week's counts: zeros stay grey, only what moved takes a colour (like the history delta line). */
.sw-nba-side--week .sw-nba-side__line b { color: var(--sw-text-muted); }
.sw-nba-side__line b.sw-nba-side__num--fixed { color: var(--sw-success-text); }
.sw-nba-side__line b.sw-nba-side__num--new { color: var(--sw-warning-text); }
.sw-nba-side__line b.sw-nba-side__num--regressed { color: var(--sw-poor-text); }
.sw-nba-side__note { margin: .625rem 0 0; font-size: var(--sw-text-xs); color: var(--sw-text-muted); line-height: 1.5; }
.sw-nba-next-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .25rem 1rem; margin: 2rem 0 .875rem; }
.sw-nba-next-head__title { font-size: var(--sw-text-xl); font-weight: 600; margin: 0; }
.sw-nba-next-head__sub { margin: 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-nba-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; align-items: start; }
@media (max-width: 767.98px) { .sw-nba-grid { grid-template-columns: minmax(0, 1fr); } }
.sw-nba-tile.sw-card { padding: var(--sw-card-pad-md); }
.sw-nba-tile__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; margin: 0 0 .5rem; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-nba-tile__title { font-size: var(--sw-text-md); font-weight: 600; line-height: 1.5; margin: 0; }
.sw-nba-tile__title a { color: var(--sw-text); text-decoration: none; }
.sw-nba-tile__title a:hover { color: var(--sw-brand-text); text-decoration: underline; text-underline-offset: 3px; }
.sw-nba-tile__more { margin-top: .75rem; }

/* ── Techstack: release status (PUB-09, #1051) ──
   One panel above the categories: the verdict line, what needs attention with
   its reason and next step, the maintained ones folded away. Panel standard
   (#1033): surface, hairline, compact padding, 16 px title. */
.sw-ts-releases.sw-card { height: auto; margin: 0 0 1.5rem; }
.sw-ts-releases .sw-card-title { margin-bottom: .25rem; }
.sw-ts-releases__sub { margin: 0; max-width: 70ch; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
.sw-ts-releases__figures { margin: 1rem 0 0; }
.sw-ts-releases__figures .sw-light { margin-right: .375rem; }
.sw-ts-releases__note { margin: 1rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
.sw-ts-releases__allclear { display: flex; align-items: center; gap: .5rem; margin: 1rem 0 0; font-size: var(--sw-text-md); color: var(--sw-text); }
.sw-ts-releases__list { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-direction: column; }
.sw-ts-release { padding: 1rem 0; border-top: 1px solid var(--sw-border); }
.sw-ts-release:last-child { padding-bottom: 0; }
.sw-ts-release__top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; }
.sw-ts-release__name { font-size: var(--sw-text-md); font-weight: 600; color: var(--sw-text); }
.sw-ts-release__version { font-weight: 500; color: var(--sw-text-secondary); font-variant-numeric: tabular-nums; }
.sw-ts-release__reason { margin: .375rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text-secondary); line-height: 1.55; max-width: 72ch; }
.sw-ts-release__advice { display: flex; align-items: flex-start; gap: .5rem; margin: .5rem 0 0; font-size: var(--sw-text-base); color: var(--sw-text); line-height: 1.55; max-width: 72ch; }
.sw-ts-release__advice svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: .1rem; color: var(--sw-brand-text); }
.sw-ts-releases__more { margin-top: 1rem; border-top: 1px solid var(--sw-border); border-radius: var(--sw-radius-inline); }
.sw-ts-releases__current { list-style: none; margin: 0; padding: .25rem 1.25rem .75rem; display: flex; flex-direction: column; gap: .625rem; }
.sw-ts-releases__current li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .25rem 1rem; }
.sw-ts-release__meta { font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-ts-releases__source { margin: 1.25rem 0 0; padding-top: 1rem; border-top: 1px solid var(--sw-border); font-size: var(--sw-text-xs); color: var(--sw-text-muted); line-height: 1.5; }
.sw-ts-releases__source a { color: var(--sw-text-secondary); }
.sw-ts-version.sw-rating-chip { white-space: nowrap; }
.sw-ts-release__id { display: inline-flex; align-items: center; gap: .625rem; min-width: 0; }
.sw-ts-release__reason, .sw-ts-release__advice { padding-left: calc(32px + .625rem); }
.sw-ts-releases__current li { align-items: center; }
@media (max-width: 575.98px) { .sw-ts-release__reason, .sw-ts-release__advice { padding-left: 0; } }
.sw-ts-releases__zero { opacity: .55; }

/* ── Homepage (#1114) ──
   Hero with the free check, the result as it looks, the area explorer, three steps,
   the plans in short, FAQ, the check once more. Tokens only; every section is one
   quiet surface, no stat tiles, no rings, no brand-coloured left border. */
.sw-lp-section { padding: 5rem 0; }
.sw-lp-section--subtle { background: var(--sw-bg-subtle); }
.sw-lp-section--tight { padding: 3rem 0; }
.sw-lp-h1 { font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.5rem); font-weight: 700; letter-spacing: -0.025em; line-height: 1.15; color: var(--sw-text); margin: 0 0 1rem; }
.sw-lp-h2 { font-size: var(--sw-text-5xl); font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; color: var(--sw-text); margin: 0 0 0.75rem; }
.sw-lp-lead { font-size: var(--sw-text-xl); color: var(--sw-text-secondary); line-height: 1.55; max-width: 36rem; margin: 0 0 1.75rem; }
.sw-lp-sub { font-size: var(--sw-text-lg); color: var(--sw-text-secondary); line-height: 1.6; max-width: 40rem; margin: 0 0 2.5rem; }
.sw-lp-note { font-size: var(--sw-text-sm); color: var(--sw-text-muted); margin: 0.875rem 0 0; }
.sw-lp-more { margin: 1.25rem 0 0; font-size: var(--sw-text-base); }
.sw-lp-link { color: var(--sw-brand-text); font-weight: 600; text-decoration: none; }
.sw-lp-link:hover { text-decoration: underline; color: var(--sw-link-hover); }
.sw-lp-icon { display: grid; place-items: center; flex-shrink: 0; width: 40px; height: 40px; border-radius: var(--sw-radius-control); background: var(--sw-brand-tint); color: var(--sw-brand-text); }
.sw-lp-icon svg { width: 22px; height: 22px; }

/* Hero */
.sw-lp-hero { padding: 4rem 0 4.5rem; }
.sw-lp-hero__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 3rem; align-items: center; }
.sw-lp-check { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); box-shadow: var(--sw-shadow-lg); overflow: hidden; }
.sw-lp-check__form { padding: 1.75rem; }
.sw-lp-check__form h2 { font-size: var(--sw-text-2xl); font-weight: 700; margin: 0 0 0.25rem; }
.sw-lp-check__form > p { color: var(--sw-text-secondary); margin: 0 0 1.25rem; font-size: var(--sw-text-md); }
.sw-lp-check .sw-home-scan-form,
.sw-lp-final__form .sw-home-scan-form { max-width: none; background: none; border: 0; padding: 0; }
.sw-lp-check .sw-home-scan-form .sw-form-label,
.sw-lp-final__form .sw-home-scan-form .sw-form-label { color: var(--sw-text); }
.sw-lp-check .sw-home-scan-row,
.sw-lp-final__form .sw-home-scan-row { flex-wrap: wrap; }
.sw-lp-check .sw-home-scan-row .sw-btn,
.sw-lp-final__form .sw-home-scan-row .sw-btn { flex: 1 1 auto; }
.sw-lp-check__areas { background: var(--sw-bg-subtle); padding: 1.25rem 1.75rem 1.5rem; border-top: 1px solid var(--sw-border); }
.sw-lp-check__areas h3 { font-size: var(--sw-text-sm); font-weight: 600; color: var(--sw-text-secondary); margin: 0 0 0.875rem; }
.sw-lp-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; list-style: none; padding: 0; margin: 0; }
.sw-lp-chips li { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--sw-text-sm); color: var(--sw-text); background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-btn); padding: 0.3rem 0.75rem; }

/* The result as it looks */
.sw-lp-show { margin: 0; }
.sw-lp-show__bar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.sw-lp-show__title { font-size: var(--sw-text-2xl); font-weight: 700; margin: 0; color: var(--sw-text); }
.sw-lp-show__title span { display: block; font-size: var(--sw-text-xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sw-text-secondary); margin-bottom: 0.125rem; }
.sw-lp-show__top { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: 1rem; }
.sw-lp-show__card { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 1.25rem; }
.sw-lp-show__card h3 { font-size: var(--sw-text-md); font-weight: 600; margin: 0 0 0.75rem; color: var(--sw-text); }
.sw-lp-show__lead { font-size: var(--sw-text-lg); color: var(--sw-text); line-height: 1.5; margin: 0 0 1rem; }
.sw-lp-show__score { display: flex; align-items: center; gap: 0.875rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
.sw-lp-show__num { font-size: var(--sw-text-5xl); font-weight: 700; letter-spacing: -0.02em; line-height: 1; color: var(--sw-text); font-variant-numeric: tabular-nums; }
.sw-lp-show__num small { font-size: var(--sw-text-xl); font-weight: 600; color: var(--sw-text-secondary); }
.sw-lp-show__chart { height: 150px; padding: 0; }
.sw-lp-show__foot { margin: 0.5rem 0 0; font-size: var(--sw-text-xs); color: var(--sw-text-muted); }
.sw-lp-show__lever { margin: 1rem 0; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 0.875rem 1.25rem; font-size: var(--sw-text-md); color: var(--sw-text); }

/* Area explorer: vertical tabs on desktop, scrollable pills below */
.sw-lp-explorer { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 2rem; align-items: start; }
.sw-lp-explorer__list { display: flex; flex-direction: column; gap: 0.25rem; position: sticky; top: calc(var(--sw-navbar-height) + 1rem); }
.sw-lp-tab { display: flex; align-items: center; gap: 0.75rem; min-height: 48px; padding: 0.625rem 0.875rem; background: transparent; border: 0; border-radius: var(--sw-radius-inline); color: var(--sw-text-secondary); text-align: left; font: inherit; font-size: var(--sw-text-md); font-weight: 500; cursor: pointer; }
.sw-lp-tab svg { width: 20px; height: 20px; flex-shrink: 0; }
.sw-lp-tab:hover { background: var(--sw-bg-subtle); color: var(--sw-text); }
.sw-lp-tab[aria-selected="true"] { background: var(--sw-brand-tint); color: var(--sw-text); font-weight: 600; }
.sw-lp-tab[aria-selected="true"] svg { color: var(--sw-brand-text); }
.sw-lp-tab:focus-visible { outline: 2px solid var(--sw-focus-ring); outline-offset: 2px; }
.sw-lp-panel { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 2rem; }
.sw-lp-panel h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem; font-size: var(--sw-text-3xl); font-weight: 700; letter-spacing: -0.01em; margin: 0 0 0.5rem; }
.sw-lp-panel__benefit { font-size: var(--sw-text-xl); color: var(--sw-text-secondary); line-height: 1.5; margin: 0 0 1.75rem; }
.sw-lp-panel h4 { font-size: var(--sw-text-sm); font-weight: 600; color: var(--sw-text-secondary); margin: 0 0 0.75rem; }
.sw-lp-panel__more { margin: auto 0 0; padding-top: 1rem; font-size: var(--sw-text-sm); }
.sw-lp-panel__more a { display: inline-flex; align-items: center; min-height: 44px; }
.sw-lp-explorer__panels { display: grid; }
.sw-lp-explorer__panels > .sw-lp-panel { grid-area: 1 / 1; align-self: stretch; display: flex; flex-direction: column; }
.sw-lp-explorer__panels > .sw-lp-panel[hidden] { display: flex !important; visibility: hidden; }
.sw-lp-finds { list-style: none; padding: 0; margin: 0 0 1.75rem; display: grid; gap: 0.625rem; }
.sw-lp-finds li { display: grid; grid-template-columns: auto 1fr; gap: 0.75rem; background: var(--sw-bg-subtle); border-radius: var(--sw-radius-inline); padding: 0.875rem 1rem; color: var(--sw-text); font-size: var(--sw-text-md); line-height: 1.5; }
.sw-lp-finds .sw-light { margin: 0.15rem 0 0; align-self: start; }
.sw-lp-advice { background: color-mix(in srgb, var(--sw-brand) 8%, var(--sw-surface)); border-radius: var(--sw-radius-inline); padding: 1.25rem; }
.sw-lp-advice p { margin: 0 0 0.5rem; color: var(--sw-text-secondary); line-height: 1.6; font-size: var(--sw-text-md); }
.sw-lp-advice p:last-child { margin: 0; }
.sw-lp-advice strong { color: var(--sw-text); }
.sw-lp-advice__head { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; color: var(--sw-text); margin-bottom: 0.625rem; }
.sw-lp-advice__head svg { width: 20px; height: 20px; color: var(--sw-brand-text); }

/* Steps folded into the result, the plans in short, trust, closing action (#1236) */
.sw-lp-cmp__focus { background: color-mix(in srgb, var(--sw-brand) 7%, transparent); }
.sw-lp-price { display: block; margin-top: 0.25rem; font-size: var(--sw-text-2xl); font-weight: 700; letter-spacing: -0.01em; color: var(--sw-text); }
.sw-lp-price small { font-size: var(--sw-text-sm); font-weight: 500; color: var(--sw-text-secondary); margin-left: 0.25rem; }
.sw-lp-ticks { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.5rem; }
.sw-lp-ticks li { display: grid; grid-template-columns: 18px 1fr; gap: 0.5rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); line-height: 1.5; }
.sw-lp-ticks svg { width: 18px; height: 18px; color: var(--sw-success-text); margin-top: 0.15rem; }

.sw-lp-facts { list-style: none; display: flex; flex-wrap: wrap; gap: 0.25rem 0; padding: 0; margin: 0 0 0 -1.25rem; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); line-height: 1.6; }
.sw-lp-facts li::before { content: "\00b7"; display: inline-block; width: 1.25rem; text-align: center; }
.sw-lp-hero__copy { overflow: hidden; }
.sw-lp-steps-inline { list-style: none; display: flex; flex-wrap: wrap; gap: 0.75rem 2rem; padding: 0; margin: 0 0 1.5rem; color: var(--sw-text); font-size: var(--sw-text-lg); font-weight: 500; }
.sw-lp-steps-inline li { display: inline-flex; align-items: center; gap: 0.625rem; }
.sw-lp-show__access { margin-top: 1rem; }
.sw-lp-show__areas { margin-top: 1rem; }
.sw-lp-show__rows { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 2.5rem; }
.sw-lp-show__rows li { padding: 0.875rem 0; border-top: 1px solid var(--sw-border); display: grid; gap: 0.375rem; align-content: start; }
.sw-lp-show__row-head { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; font-weight: 600; font-size: var(--sw-text-md); color: var(--sw-text); }
.sw-lp-show__row-text { margin: 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); line-height: 1.45; }
.sw-lp-trust { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 3rem; align-items: start; }
.sw-lp-trust .sw-lp-sub { margin-bottom: 0; }
.sw-lp-trust__list { margin: 0; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); }
.sw-lp-trust__list > div { padding: 1.125rem 1.5rem; }
.sw-lp-trust__list > div + div { border-top: 1px solid var(--sw-border); }
.sw-lp-trust__list dt { font-weight: 600; color: var(--sw-text); font-size: var(--sw-text-lg); margin-bottom: 0.25rem; }
.sw-lp-trust__list dd { margin: 0; color: var(--sw-text-secondary); font-size: var(--sw-text-md); line-height: 1.55; }
.sw-lp-pricebar { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); overflow: hidden; }
.sw-lp-pricebar li { padding: 1.5rem; display: flex; flex-direction: column; gap: 0.25rem; }
.sw-lp-pricebar li + li { border-left: 1px solid var(--sw-border); }
.sw-lp-pricebar h3 { font-size: var(--sw-text-xl); font-weight: 600; margin: 0; color: var(--sw-text); }
.sw-lp-pricebar p { margin: 0.375rem 0 0.75rem; font-size: var(--sw-text-md); color: var(--sw-text-secondary); line-height: 1.5; flex: 1; }
.sw-lp-pricebar__link { display: inline-flex; align-items: center; min-height: 44px; }
.sw-lp-pricebar__more { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 0.5rem 1.5rem; }
.sw-lp-pricebar__more a { display: inline-flex; align-items: center; min-height: 44px; scroll-margin-top: calc(var(--sw-navbar-height) + 1rem); }
.sw-lp-pricebar__audience { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 1.5rem; font-size: var(--sw-text-base); color: var(--sw-text-secondary); }
.sw-lp-final__alt { display: inline-flex; align-items: center; min-height: 44px; font-size: var(--sw-text-base); }
.sw-lp-final .sw-lp-note { margin-top: 0.5rem; }
.sw-lp-faq { max-width: 760px; }
#faq { scroll-margin-top: calc(var(--sw-navbar-height) + 1rem); }
.sw-lp-final { max-width: 760px; margin: 0 auto; text-align: center; background: color-mix(in srgb, var(--sw-brand) 8%, var(--sw-surface)); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 3rem 2rem; }
.sw-lp-final .sw-lp-sub { margin: 0 auto 1.75rem; max-width: 34rem; }
.sw-lp-final__form { max-width: 560px; margin: 0 auto; text-align: left; }

@media (max-width: 991.98px) {
    .sw-lp-hero { padding-top: 2.75rem; }
    .sw-lp-hero__grid { grid-template-columns: 1fr; gap: 0; }
    .sw-lp-hero__copy { display: contents; }
    .sw-lp-h1, .sw-lp-lead { order: 1; }
    .sw-lp-check { order: 2; margin: 0 0 1.25rem; }
    .sw-lp-facts { order: 3; flex-direction: column; margin-left: 0; }
    .sw-lp-facts li::before { display: none; }
    .sw-lp-show__top { grid-template-columns: 1fr; }
    .sw-lp-trust { grid-template-columns: 1fr; gap: 1.5rem; }
    .sw-lp-explorer { grid-template-columns: 1fr; gap: 1rem; }
    .sw-lp-explorer__panels > .sw-lp-panel[hidden] { display: none !important; }
    .sw-lp-explorer__list { -webkit-mask-image: linear-gradient(to right, black calc(100% - 2.5rem), transparent); mask-image: linear-gradient(to right, black calc(100% - 2.5rem), transparent); flex-direction: row; overflow-x: auto; position: static; padding-bottom: 0.5rem; scroll-snap-type: x mandatory; margin: 0 calc(-0.5 * var(--bs-gutter-x)); padding-left: calc(0.5 * var(--bs-gutter-x)); padding-right: calc(0.5 * var(--bs-gutter-x)); }
    .sw-lp-tab { flex-shrink: 0; scroll-snap-align: start; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-btn); min-height: 44px; padding: 0.5rem 0.875rem; scroll-margin-inline: 2.5rem; }
    .sw-lp-panel { padding: 1.5rem; }
    .sw-lp-panel h3 { font-size: var(--sw-text-2xl); }
}

@media (max-width: 767.98px) {
    .sw-lp-section { padding: 3.5rem 0; }
    .sw-lp-h2 { font-size: var(--sw-text-3xl); }
    .sw-lp-section--tight { padding: 2.5rem 0; }
    .sw-lp-show__rows { grid-template-columns: 1fr; }
    .sw-lp-show__row-head { flex-wrap: wrap; }
    .sw-lp-show__rows .sw-rating-chip { white-space: nowrap; }
    .sw-lp-pricebar { grid-template-columns: 1fr; }
    .sw-lp-pricebar li + li { border-left: 0; border-top: 1px solid var(--sw-border); }
    .sw-lp-steps-inline { flex-direction: column; gap: 0.625rem; }
}

@media (max-width: 575.98px) {
    .sw-lp-show { margin: 0; }
    .sw-lp-final { padding: 2rem 1.25rem; }
}

/* ── Billing address form (#1077) ──
   Panel standard of the profile page (#1033): one panel per topic, hints small and
   muted, one primary action. The right column shows the address as it is printed on
   the next invoice; a phone gets one column with the preview under the form. */
.sw-bill-addr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(17rem, 22rem); gap: 1.5rem; align-items: start; }
.sw-bill-addr__form { display: flex; flex-direction: column; gap: 1rem; min-width: 0; margin: 0; }
.sw-bill-addr__fields { display: flex; flex-direction: column; gap: 1.25rem; margin-top: 1.25rem; }
.sw-bill-addr__row { display: grid; grid-template-columns: 9rem minmax(0, 1fr); gap: 1rem; align-items: start; }
.sw-bill-addr__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; }
.sw-bill-preview { position: sticky; top: 1.5rem; }
.sw-bill-preview__paper { margin-top: 1.25rem; padding: 1.25rem; min-height: 11rem; border: 1px solid var(--sw-border); border-radius: var(--sw-radius-inline); background: var(--sw-bg-subtle); }
.sw-bill-preview__label { margin: 0 0 .5rem; font-size: var(--sw-text-xs); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--sw-text-muted); }
.sw-bill-preview__block { margin: 0; font-style: normal; font-size: var(--sw-text-md); line-height: 1.6; color: var(--sw-text); overflow-wrap: anywhere; }
.sw-bill-preview__line--company { font-weight: 600; }
.sw-bill-preview__line--muted { margin-top: .5rem; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-bill-preview__empty { margin: 0; font-size: var(--sw-text-base); line-height: 1.55; color: var(--sw-text-secondary); }
.sw-bill-preview__block[hidden], .sw-bill-preview__line[hidden], .sw-bill-preview__empty[hidden] { display: none; }
@media (max-width: 991.98px) {
    .sw-bill-addr { grid-template-columns: minmax(0, 1fr); }
    .sw-bill-preview { position: static; }
}

/* #1077: one quiet line where a plan card had a disabled button ("Current plan", "Included"). */
.sw-billing-card-state { display: flex; align-items: center; justify-content: center; min-height: 2.75rem; margin: 0; font-size: var(--sw-text-base); font-weight: 500; color: var(--sw-text-secondary); }

/* #1077: the add-shop / add-competitor submit is the page's one primary action. While no domain
   is typed it is disabled, which painted it the neutral grey of every other disabled button and
   made it read as not-the-action. It keeps the brand hue, tinted, until the input is valid. */
.sw-btn-primary.sw-shop-url-bar-btn.sw-btn-disabled { background: var(--sw-brand-tint); border-color: transparent; color: var(--sw-brand-text) !important; }

/* ── Mobile 390px, second pass (#1085) ── */
@media (max-width: 767.98px) {
    /* /try result: the Automation Curve label ("Stufe 2 von 5: Maschinenlesbar") is one
       nowrap badge; beside the name it pushed into the traffic light. The badge drops
       under the name and may wrap. */
    .sw-result-panel__check-name { flex-wrap: wrap; row-gap: 4px; }
    .sw-result-panel__cnt { white-space: normal; }

    /* Billing: the statement column's min-content (the invoice table) widened the
       whole grid to 399 px. Let the column shrink, and turn the invoice table into
       stacked rows: number and amount on one line, date and PDF on the next. */
    .sw-billing-ledger-grid { grid-template-columns: minmax(0, 1fr); }
    .sw-billing-ledger-grid > * { min-width: 0; }
    .sw-billing-invoices-inline .sw-invoice-table { display: block; overflow: visible; }
    .sw-billing-invoices-inline .sw-invoice-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    .sw-billing-invoices-inline .sw-invoice-table tbody { display: block; }
    .sw-billing-invoices-inline .sw-invoice-table tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "num amount" "date dl"; gap: .25rem 1rem; align-items: center; padding: .875rem 1rem; border-bottom: 1px solid var(--sw-border); }
    .sw-billing-invoices-inline .sw-invoice-table tr:last-child { border-bottom: 0; }
    .sw-billing-invoices-inline .sw-invoice-table td { display: block; padding: 0; border: 0; }
    .sw-billing-invoices-inline .sw-invoice-table td:nth-child(1) { grid-area: num; white-space: nowrap; }
    .sw-billing-invoices-inline .sw-invoice-table td:nth-child(2) { grid-area: date; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
    .sw-billing-invoices-inline .sw-invoice-table td:nth-child(3) { grid-area: amount; white-space: nowrap; }
    .sw-billing-invoices-inline .sw-invoice-table td:nth-child(4) { grid-area: dl; }
    .sw-billing-invoices-inline .sw-invoice-desc { white-space: normal; }

    /* History calendar: exactly ten weeks fill the width beside the weekday column, so the
       oldest visible column is whole instead of a sliver under the sticky labels. The
       calendar still scrolls to older weeks and opens on the newest. 40px = weekday column
       and its gap, 36px = nine gaps. */
    .sw-history-cal-wrap { container-type: inline-size; }
    .sw-history-cal-wrap .sw-history-cal { --sw-hist-cell: calc((100cqw - 40px - 36px) / 10) !important; --sw-hist-gap: 4px !important; }
}

/* ── Solutions pages (#1154): "Für Shop-Betreiber" and "Für Agenturen" ──
   The pictures on these pages are the app's own components (dashboard week, action tile,
   competitor bars, score line, alert rows, members list, the weekly e-mail) and the
   homepage's result card, so they bring their own styles. Only the page layout lives here:
   sections, the neutral frame with its "Beispiel" bar, the week strip and the step rail. */
.sw-sol-eyebrow { display: inline-flex; align-items: center; gap: .5rem; margin: 0 0 1rem; }
.sw-sol-eyebrow svg { width: 18px; height: 18px; }
.sw-sol-hero__intro { max-width: 46rem; }
.sw-sol-actions { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin-top: 1.75rem; }
.sw-sol-actions--center { justify-content: center; }
.sw-sol-note { display: flex; align-items: center; gap: .4rem; margin: .875rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); }
.sw-sol-note svg { width: 16px; height: 16px; }
.sw-sol-sample { font-size: var(--sw-text-xs); color: var(--sw-text-muted); margin: .75rem 0 0; }
.sw-sol-when { display: block; margin: .625rem 0 .25rem; }

/* Section heads and text + picture sections */
.sw-sol-head { max-width: 46rem; margin-bottom: 2rem; }
.sw-sol-head .sw-lp-sub { margin-bottom: 0; }
.sw-sol-split { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 3rem; align-items: center; }
.sw-sol-split--rev { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
.sw-sol-split h2 { margin-bottom: .75rem; }
.sw-sol-split p.sw-lp-sub { margin-bottom: 1.25rem; }
.sw-sol-split .sw-lp-ticks b, .sw-sol-rail .sw-lp-ticks b { color: var(--sw-text); font-weight: 600; }

/* The neutral frame around an example: a quiet window with the "Beispiel" badge in its bar */
.sw-sol-frame { margin: 0; background: var(--sw-bg); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); box-shadow: var(--sw-shadow-lg); padding: 1.25rem; min-width: 0; }
.sw-sol-frame__bar { display: flex; justify-content: space-between; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: 1rem; }
.sw-sol-frame__title { margin: 0; font-size: var(--sw-text-lg); font-weight: 700; color: var(--sw-text); }
.sw-sol-frame__title span { display: block; font-size: var(--sw-text-xs); font-weight: 600; color: var(--sw-text-secondary); margin-bottom: .125rem; }
.sw-sol-frame .sw-figures { margin-top: .875rem; }
.sw-sol-stack { display: grid; gap: 1rem; min-width: 0; }

/* The real e-mail, sized to its content by frame_fit_controller.js; the height is a close first guess. */
.sw-sol-mail { display: block; width: 100%; height: 44rem; border: 0; border-radius: var(--sw-radius-inline); }

/* Components that are list items in the app, shown alone or stacked */
.sw-sol-tiles { list-style: none; margin: 0 0 .75rem; padding: 0; display: grid; gap: .75rem; }
.sw-sol-tiles:last-child { margin-bottom: 0; }

/* Two things side by side (self / hand on, score line / competitors, Free / Standard) */
.sw-sol-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; align-items: start; }
.sw-sol-pair--even { align-items: stretch; }
.sw-sol-pair .sw-pricing-card--featured, .sw-sol-pair .sw-pricing-card--featured:hover { transform: none; }

/* The week (or the client) at a glance: four stations on a line */
.sw-sol-strip { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; position: relative; }
.sw-sol-strip li { position: relative; padding: 0 1rem 0 0; }
.sw-sol-strip li::before { content: ""; position: absolute; top: 20px; left: 48px; right: 8px; height: 2px; background: var(--sw-border); }
.sw-sol-strip li:last-child::before { display: none; }
.sw-sol-strip .sw-lp-icon { position: relative; z-index: 1; margin-bottom: .875rem; }
.sw-sol-strip__when { display: block; font-size: var(--sw-text-xs); font-weight: 600; color: var(--sw-brand-text); margin-bottom: .25rem; }
.sw-sol-strip h3 { font-size: var(--sw-text-lg); font-weight: 600; margin: 0 0 .25rem; color: var(--sw-text); }
.sw-sol-strip p { margin: 0; font-size: var(--sw-text-md); color: var(--sw-text-secondary); line-height: 1.5; }
.sw-sol-strip a { color: inherit; text-decoration: none; }
.sw-sol-strip a:hover h3 { color: var(--sw-brand-text); }
.sw-sol-strip-wrap { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-panel); padding: 1.75rem; }
.sw-sol-strip-wrap--hero { margin-top: 3rem; }

/* The step rail: one numbered moment per row, text left, picture right */
.sw-sol-rail { list-style: none; margin: 0; padding: 0; }
.sw-sol-rail > li { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 1.5rem; padding-bottom: 3.5rem; position: relative; }
.sw-sol-rail > li:last-child { padding-bottom: 0; }
.sw-sol-rail > li:not(:last-child)::before { content: ""; position: absolute; left: 21px; top: 48px; bottom: 4px; width: 2px; background: var(--sw-border); }
.sw-sol-rail__n { width: 44px; height: 44px; border-radius: 50%; background: var(--sw-brand-tint); color: var(--sw-brand-text); display: grid; place-items: center; font-weight: 700; }
.sw-sol-rail__n svg { width: 22px; height: 22px; }
.sw-sol-rail__body { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: 2.5rem; align-items: start; }
.sw-sol-rail__body > * { min-width: 0; }
.sw-sol-rail h3 { font-size: var(--sw-text-3xl); font-weight: 700; letter-spacing: -.01em; margin: 0 0 .75rem; color: var(--sw-text); }
.sw-sol-rail__text > p { color: var(--sw-text-secondary); font-size: var(--sw-text-lg); line-height: 1.6; margin: 0 0 1.25rem; }

@media (max-width: 991.98px) {
    .sw-sol-split, .sw-sol-split--rev { grid-template-columns: 1fr; gap: 2rem; }
    .sw-sol-split--rev > :first-child { order: 2; }
    .sw-sol-pair { grid-template-columns: 1fr; }
    .sw-sol-strip { grid-template-columns: 1fr 1fr; gap: 1.75rem 0; }
    .sw-sol-strip li:nth-child(2)::before { display: none; }
    .sw-sol-rail__body { grid-template-columns: 1fr; gap: 1.5rem; }
}
@media (max-width: 767.98px) {
    .sw-sol-strip { grid-template-columns: 1fr; gap: 1.25rem; }
    .sw-sol-strip li { padding: 0; }
    .sw-sol-strip li > a { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 0 1rem; }
    .sw-sol-strip li > a > :not(.sw-lp-icon) { grid-column: 2; }
    .sw-sol-strip li::before { display: block; left: 19px; top: 44px; bottom: -1.25rem; right: auto; width: 2px; height: auto; }
    .sw-sol-strip li:nth-child(2)::before { display: block; }
    .sw-sol-strip li:last-child::before { display: none; }
    .sw-sol-strip .sw-lp-icon { margin: 0; grid-column: 1; grid-row: 1 / span 3; }
    .sw-sol-strip-wrap { padding: 1.25rem; }
    .sw-sol-rail > li { grid-template-columns: 1fr; gap: .75rem; }
    .sw-sol-rail > li::before { display: none; }
    .sw-sol-rail h3 { font-size: var(--sw-text-2xl); }
}
@media (max-width: 575.98px) {
    .sw-sol-frame { padding: .875rem; }
}

/* #1219: plan change confirmation + the line under a plan's button */
.sw-billing-card-hint { margin: .5rem 0 0; font-size: var(--sw-text-sm); color: var(--sw-text-secondary); text-align: center; }
.sw-billing-change__lead { font-size: var(--sw-text-base); margin-bottom: 1.25rem; }
.sw-billing-change__facts { display: grid; grid-template-columns: max-content 1fr; gap: .5rem 1.5rem; margin: 0 0 1.25rem; }
.sw-billing-change__facts dt { color: var(--sw-text-secondary); font-weight: 500; }
.sw-billing-change__facts dd { margin: 0; }
.sw-billing-change__muted { color: var(--sw-text-secondary); }

/* ── CSP: classes that replaced static style="" attributes (#1222) ──────────
   Last in the file on purpose: they stand in for inline styles, which beat any
   class, so they must win ties by order. Per-render values (a loop index, a bar
   width) cannot be classes and still use style=""; style-src keeps 'unsafe-inline'
   for those until they move to a data attribute plus a Stimulus controller. */

/* Stagger index of the entrance animations (animation-delay: calc(var(--i) * ...)). */
.sw-i-0 { --i: 0; }
.sw-i-1 { --i: 1; }
.sw-i-2 { --i: 2; }
.sw-i-3 { --i: 3; }
.sw-i-4 { --i: 4; }
.sw-i-5 { --i: 5; }

/* Scroll-reveal stagger on the public content pages. */
.sw-reveal.sw-delay-05 { transition-delay: 0.05s; }
.sw-reveal.sw-delay-1 { transition-delay: 0.1s; }
.sw-reveal.sw-delay-2 { transition-delay: 0.2s; }
.sw-reveal.sw-delay-5 { transition-delay: 0.5s; }

/* The one-message pages (newsletter and waitlist unsubscribe). */
.sw-hero.sw-hero--page {
    min-height: 50vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
}
.sw-hero-sub.sw-hero-sub--narrow { max-width: 480px; }
