/**
 * Pols — Frontend Application Layer stylesheet (Phase 4)
 *
 * Styles the standalone HTML pages served at /pols/* (dashboard, editor,
 * settings, presenters, login, network). No WordPress theme or admin
 * chrome is loaded — this stylesheet is the entire visual foundation.
 *
 * Branding CSS custom properties (the --md-sys-color-* brand roles, their
 * --pols-primary / -secondary / -tertiary aliases, --pols-font) are
 * injected per-site via Pols\Branding.
 */

/*──────────────────────────────────────────
 * Base tokens
 *
 * The --m3-* vocabulary comes from tokens.css (loaded before this file).
 * The legacy --pols-* app vars below are ALIASES onto those shared tokens
 * so the whole component inventory keeps working while components are
 * migrated to M3 per-surface (PHASE_M3_EXPRESSIVE).
 *────────────────────────────────────────*/
:root {
    /* Brand colours (--pols-primary, --pols-secondary, --pols-tertiary,
       --pols-accent and their -on / -container names) are aliases of the
       --md-sys-color-* roles in tokens.css, filled per institution by
       Branding::render_css_vars() in <head> (alpha.71). Do not redefine them
       here: a literal would replace the alias with a raw seed. --pols-font
       lives in tokens.css too (alpha.72), next to the type roles. */

    --pols-bg:           var(--m3-surface);
    --pols-surface:      var(--m3-surface-container-lowest);
    --pols-surface-alt:  var(--m3-surface-container-low);
    --pols-border:       var(--m3-outline-variant);
    --pols-border-soft:  var(--m3-surface-container-high);
    --pols-text:         var(--m3-on-surface);
    --pols-text-muted:   var(--m3-on-surface-variant);
    --pols-text-faint:   var(--m3-outline);
    --pols-danger:       #c62828;
    --pols-warning:      #ed6c02;
    /* --pols-success is the fixed token in tokens.css (alpha.70): redefining
       it here would override that on every app page. */

    --pols-radius:       var(--m3-shape-md);
    --pols-radius-sm:    var(--m3-shape-sm);
    --pols-radius-lg:    var(--m3-shape-lg);
    --pols-shadow-sm:    var(--m3-elev-1);
    --pols-shadow:       var(--m3-elev-2);
    --pols-shadow-lg:    var(--m3-elev-3);

    --pols-nav-height:   60px;
}

/*──────────────────────────────────────────
 * Reset / base
 *────────────────────────────────────────*/
*, *::before, *::after {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body.pols-app {
    font-family: var(--pols-font);
    color: var(--pols-text);
    background: var(--pols-bg);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    line-height: 1.5;
}

.pols-app h1, .pols-app h2, .pols-app h3, .pols-app h4 {
    margin: 0 0 12px;
    color: var(--pols-text);
    line-height: 1.25;
}
.pols-app h1 { font-size: 24px; font-weight: 500; }
.pols-app h2 { font-size: 18px; font-weight: 500; }
.pols-app h3 { font-size: 15px; font-weight: 500; }
.pols-app p  { margin: 0 0 12px; }
.pols-app a:not(.pols-btn)       { color: var(--pols-primary); text-decoration: none; }
.pols-app a:not(.pols-btn):hover { text-decoration: underline; }

/*──────────────────────────────────────────
 * Top navigation bar
 *────────────────────────────────────────*/
/* Top app bar: the institution's band (alpha.87) — its primary colour as
   picked, with the band's on-colour (Branding::band_declarations(), 4.5:1 on
   any seed), no hairline border, constant elev-1 (CSS-only — no scroll
   listener allowed for an elevation change). Only the desktop links sit on
   the band; the mobile drawer below 721px keeps the surface colours. */
.pols-app-nav {
    background: var(--pols-brand-seed);
    height: var(--pols-nav-height);
    position: sticky;
    top: 0;
    z-index: 100;
    box-shadow: var(--m3-elev-1);
}

.pols-app-nav__inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 24px;
    height: 100%;
    display: flex;
    align-items: center;
    gap: 32px;
}

.pols-app-nav__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--pols-brand-seed-on);
    text-decoration: none;
    font-weight: 500;
}
.pols-app-nav__brand:hover { text-decoration: none; }

.pols-app-nav__logo {
    max-height: 32px;
    max-width: 140px;
    display: block;
    /* On a dark band a logo sits on a white plate, as in the participant
       header (the plate vars follow the band's luminance); content-box, so
       the plate adds to the logo instead of shrinking it. */
    background: var(--pols-header-logo-plate-bg, transparent);
    padding: var(--pols-header-logo-plate-pad, 0);
    border-radius: var(--m3-shape-xs);
    box-sizing: content-box;
}

.pols-app-nav__title {
    font: var(--md-sys-type-title-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-title-lg-ls);
    color: var(--pols-brand-seed-on);
}

.pols-app-nav__links {
    display: flex;
    gap: 4px;
    flex: 1;
}

/* Nav links: full-pill shape with an M3 state layer on ::before.
   The .is-active pill is the M3 navigation "active indicator". */
.pols-app-nav__link {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: 8px 14px; /* unchanged from pre-M3 so link positions don't shift */
    border-radius: var(--m3-shape-full);
    color: var(--m3-on-surface-variant);
    font: var(--md-sys-type-label-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-label-lg-ls);
    transition: color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-app-nav__link::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-app-nav__link:hover {
    color: var(--m3-on-surface);
    text-decoration: none;
}
.pols-app-nav__link:hover::before         { opacity: 0.08; }
.pols-app-nav__link:focus-visible::before { opacity: 0.10; }
.pols-app-nav__link:active::before        { opacity: 0.12; }
.pols-app-nav__link.is-active {
    background: var(--pols-secondary-container);
    color: var(--pols-on-secondary-container);
    font-weight: 500;
}

/* The links on the band (desktop). `a.` matches the specificity of
   `.pols-app a:not(.pols-btn)` above, which would otherwise colour them in
   the primary role — the band's own colour, so invisible. The active pill is
   the band inverted (on-colour fill, band text): the same ratio as the band
   for any seed — a tint over the band would need a text colour of its own,
   which turned the default teal's pill text black. The count badge is
   inverted too, and flips back inside the pill, so it keeps its shape
   whatever the tertiary is. */
@media (min-width: 721px) {
    .pols-app a.pols-app-nav__link,
    .pols-app a.pols-app-nav__link:hover {
        color: var(--pols-brand-seed-on);
    }
    .pols-app a.pols-app-nav__link.is-active {
        background: var(--pols-brand-seed-on);
        color: var(--pols-brand-seed);
    }
    .pols-app-nav .pols-app-nav__badge {
        background: var(--pols-brand-seed-on);
        color: var(--pols-brand-seed);
    }
    .pols-app-nav .pols-app-nav__link.is-active .pols-app-nav__badge {
        background: var(--pols-brand-seed);
        color: var(--pols-brand-seed-on);
    }
    .pols-app-nav__link:focus-visible {
        outline: 2px solid var(--pols-brand-seed-on);
        outline-offset: 2px;
    }
}
.pols-app-nav__brand:focus-visible,
.pols-app-nav__user-toggle:focus-visible,
.pols-app-nav__toggle:focus-visible {
    outline: 2px solid var(--pols-brand-seed-on);
    outline-offset: 2px;
}

/* Neutral bars (alpha.89, Branding::neutral_bars(): <html data-bars=
   "neutral">). The band variables already hold the surface (white here) and
   its on-colour, so the bar and its text follow. Two things a colour does
   not give:
   - the shadow: elev-1 barely shows a white bar on the near-white page, so
     it takes the presenter bars' shadow;
   - the active link: the band inverted is a near-black pill on white, far
     louder than the bar. It becomes a 12% tint of the primary with the
     primary as text (the role, so the colour as picked when it is dark,
     5:1 or more on the tint), and the count badge goes back to its own
     tertiary instead of flipping inside the pill. */
[data-bars="neutral"] .pols-app-nav {
    box-shadow: var(--pols-band-shadow);
}
@media (min-width: 721px) {
    [data-bars="neutral"] .pols-app a.pols-app-nav__link.is-active {
        background: rgba(var(--pols-primary-rgb), 0.12);
        color: var(--pols-primary);
    }
    [data-bars="neutral"] .pols-app-nav .pols-app-nav__badge,
    [data-bars="neutral"] .pols-app-nav .pols-app-nav__link.is-active .pols-app-nav__badge {
        background: var(--pols-tertiary);
        color: var(--pols-tertiary-on);
    }
}

.pols-app-nav__user {
    position: relative;
}

.pols-app-nav__user-toggle {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    background: transparent;
    border: 1px solid rgba(var(--pols-brand-seed-on-rgb), 0.38);
    border-radius: var(--m3-shape-full);
    color: var(--pols-brand-seed-on);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-app-nav__user-toggle::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-app-nav__user-toggle:hover::before         { opacity: 0.08; }
.pols-app-nav__user-toggle:focus-visible::before { opacity: 0.10; }
.pols-app-nav__user-toggle:hover {
    border-color: rgba(var(--pols-brand-seed-on-rgb), 0.6);
}

.pols-app-nav__user-chevron {
    font-size: 11px;
    color: inherit;
    transition: transform var(--m3-duration-short) var(--m3-easing-standard);
    display: inline-block;
}

/* Rotate the chevron 180deg when the dropdown is open */
.pols-app-nav__user-toggle[aria-expanded="true"] .pols-app-nav__user-chevron {
    transform: rotate(180deg);
}

.pols-app-nav__user-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 220px;
    background: var(--m3-surface-container-low);
    border-radius: var(--m3-shape-md);
    box-shadow: var(--m3-elev-2);
    padding: 8px;
    display: flex;
    flex-direction: column;
}
.pols-app-nav__user-dropdown[hidden] {
    display: none;
}

.pols-app-nav__user-info {
    padding: 8px 12px 12px;
    border-bottom: 1px solid var(--pols-border-soft);
    margin-bottom: 6px;
}

.pols-app-nav__user-email {
    font-size: 12px;
    color: var(--pols-text-muted);
    word-break: break-all;
}

.pols-app-nav__user-link {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 12px;
    background: transparent;
    border: 0;
    border-radius: var(--m3-shape-sm);
    color: var(--m3-on-surface);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    text-decoration: none;
}
.pols-app-nav__user-link::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-app-nav__user-link:hover {
    text-decoration: none;
}
.pols-app-nav__user-link:hover::before         { opacity: 0.08; }
.pols-app-nav__user-link:focus-visible::before { opacity: 0.10; }

/*──────────────────────────────────────────
 * Main content area + footer
 *────────────────────────────────────────*/
.pols-app-main {
    flex: 1;
    max-width: 1280px;
    width: 100%;
    margin: 0 auto;
    padding: 32px 24px;
}

.pols-app-footer {
    padding: 20px 24px;
    text-align: center;
    color: var(--m3-outline);
    font: var(--md-sys-type-body-sm) var(--pols-font);
    letter-spacing: var(--md-sys-type-body-sm-ls);
    border-top: 1px solid var(--m3-surface-container-high);
    background: var(--m3-surface);
}
.pols-app-footer a {
    color: var(--m3-outline);
}
.pols-app-footer a:hover {
    color: var(--pols-primary);
}

/*──────────────────────────────────────────
 * Page header
 *────────────────────────────────────────*/
.pols-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.pols-page-header__text h1 {
    margin-bottom: 4px;
}

.pols-page-header__text p {
    margin: 0;
    color: var(--pols-text-muted);
    font-size: 14px;
}

.pols-page-header__actions {
    display: flex;
    gap: 10px;
}

/*──────────────────────────────────────────
 * Buttons — M3 Expressive roles
 *
 * Mapping (class names unchanged; only the CSS meaning changed):
 *   --primary   → Filled   (brand fill, on-color state layer)
 *   --secondary → Tonal    (primary-container fill)
 *   --danger    → Outlined-danger (danger-tinted state layer on hover)
 *   --text      → Text     (transparent; also aliased by legacy --ghost)
 * State layer = ::before overlay (8% hover / 10% focus / 12% pressed),
 * expressive press = scale(0.98). Pill shape, 40px default height.
 *────────────────────────────────────────*/
.pols-btn {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 40px;
    padding: 0 24px;
    font: var(--md-sys-type-label-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-label-lg-ls);
    border-radius: var(--m3-shape-full);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    transition: box-shadow    var(--m3-duration-short) var(--m3-easing-standard),
                background-color var(--m3-duration-short) var(--m3-easing-standard),
                border-color  var(--m3-duration-short) var(--m3-easing-standard),
                color         var(--m3-duration-short) var(--m3-easing-standard),
                transform     var(--m3-duration-short) var(--m3-easing-emphasized);
    line-height: 1.2;
}
.pols-btn::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-btn:hover { text-decoration: none; }
.pols-btn:hover:not(:disabled)::before         { opacity: 0.08; }
.pols-btn:focus-visible::before                { opacity: 0.10; }
.pols-btn:active:not(:disabled)::before        { opacity: 0.12; }
.pols-btn:active:not(:disabled)                { transform: scale(0.98); }
.pols-btn:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}
/* M3 disabled spec: 12% on-surface container, 38% on-surface label. */
.pols-btn:disabled {
    cursor: not-allowed;
    transform: none;
    background: rgba(26, 28, 31, 0.12);
    border-color: transparent;
    color: rgba(26, 28, 31, 0.38);
    box-shadow: none;
}

/* Filled */
.pols-btn--primary {
    background: var(--pols-primary);
    color: var(--pols-primary-on);
    border-color: transparent;
}
.pols-btn--primary:hover:not(:disabled) {
    box-shadow: var(--m3-elev-1); /* M3 filled buttons lift, the state layer tints */
}

/* Tonal */
.pols-btn--secondary {
    background: var(--pols-primary-container);
    color: var(--pols-on-primary-container);
    border-color: transparent;
}

/* Outlined-danger: tinted state layer on hover, never a full red fill jump */
.pols-btn--danger {
    background: transparent;
    color: var(--pols-danger);
    border-color: var(--m3-outline);
}

/* Text */
.pols-btn--text {
    background: transparent;
    color: var(--pols-primary);
    border-color: transparent;
}

.pols-btn--sm { height: 32px; padding: 0 16px; font: var(--md-sys-type-label-lg) var(--pols-font); letter-spacing: var(--md-sys-type-label-lg-ls); }
.pols-btn--lg { height: 48px; padding: 0 28px; font-size: 16px; }
.pols-btn--block { width: 100%; }

/*──────────────────────────────────────────
 * Form controls
 *────────────────────────────────────────*/
.pols-field {
    margin-bottom: 16px;
}

.pols-field__label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 500;
    color: var(--pols-text);
}

.pols-field__hint {
    display: block;
    margin-top: 6px;
    font: var(--md-sys-type-body-sm) var(--pols-font);
    letter-spacing: var(--md-sys-type-body-sm-ls);
    color: var(--m3-on-surface-variant);
}

/* M3 outlined text fields. Fields stay less round than buttons (shape-sm).
   Focus = a visually 2px primary border with NO glow ring; rendered as
   1px border + 1px inset shadow so the layout never shifts. */
.pols-input,
.pols-select,
.pols-textarea {
    width: 100%;
    padding: 10px 12px;
    font: inherit;
    font-size: 14px;
    color: var(--m3-on-surface);
    background: var(--m3-surface-container-lowest);
    border: 1px solid var(--m3-outline);
    border-radius: var(--m3-shape-sm);
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard),
                box-shadow   var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-input::placeholder,
.pols-textarea::placeholder {
    color: var(--m3-outline);
}
.pols-input:focus,
.pols-select:focus,
.pols-textarea:focus {
    outline: none;
    border-color: var(--pols-primary);
    box-shadow: inset 0 0 0 1px var(--pols-primary);
}

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

.pols-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    cursor: pointer;
}

/*──────────────────────────────────────────
 * Cards
 *────────────────────────────────────────*/
.pols-card {
    background: var(--pols-surface);
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius);
    padding: 20px;
    box-shadow: var(--pols-shadow-sm);
}

.pols-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

/*──────────────────────────────────────────
 * Alerts / messages
 *────────────────────────────────────────*/
.pols-alert {
    padding: 12px 16px;
    border-radius: var(--pols-radius-sm);
    margin-bottom: 16px;
    font-size: 14px;
    border: 1px solid transparent;
}
.pols-alert--error {
    background: var(--md-sys-color-error-container);
    border-color: color-mix(in srgb, var(--md-sys-color-error) 30%, transparent);
    color: var(--md-sys-color-on-error-container);
}
.pols-alert--success {
    background: var(--pols-success-container);
    border-color: color-mix(in srgb, var(--pols-success) 30%, transparent);
    color: var(--pols-on-success-container);
}
.pols-alert--info {
    background: #e7f0fa;
    border-color: #bdd4ef;
    color: #1d4a85;
}
.pols-alert--warning {
    background: #fff4e5;
    border-color: #fddaa5;
    color: #7a3e00;
}

/*──────────────────────────────────────────
 * Login / forgot-password shell
 *────────────────────────────────────────*/
/* M3: flat tonal surface (the old primary-tinted gradient fought the
   tonal ladder); the card carries the hierarchy via shape-xxl + elev-2. */
body.pols-auth {
    background: var(--m3-surface);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.pols-auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--m3-surface-container-lowest);
    border-radius: var(--m3-shape-xxl);
    box-shadow: var(--m3-elev-2);
    padding: 36px 32px;
}

.pols-auth-card__brand {
    text-align: center;
    margin-bottom: 24px;
}
.pols-auth-card__brand img {
    max-height: 60px;
    max-width: 220px;
}
.pols-auth-card__brand h1 {
    margin: 12px 0 4px;
    font-size: 20px;
    color: var(--pols-primary);
}
.pols-auth-card__brand p {
    margin: 0;
    color: var(--pols-text-muted);
    font-size: 13px;
}

/* Wider variant for forms with more fields (institution signup). */
.pols-auth-card--wide {
    max-width: 640px;
}

/* Two-column field layout — stacks on narrow viewports. */
.pols-field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}
@media (max-width: 520px) {
    .pols-field-row {
        grid-template-columns: 1fr;
    }
}

/* Text input with a fixed trailing label (e.g. ".pols.me"). */
.pols-input-suffix {
    display: flex;
    align-items: stretch;
}
.pols-input-suffix .pols-input {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.pols-input-suffix__addon {
    display: flex;
    align-items: center;
    padding: 0 12px;
    font-size: 14px;
    color: var(--m3-on-surface-variant);
    background: var(--m3-surface-container-low);
    border: 1px solid var(--m3-outline);
    border-left: none;
    border-top-right-radius: var(--m3-shape-sm);
    border-bottom-right-radius: var(--m3-shape-sm);
    white-space: nowrap;
}

.pols-field--checkbox {
    display: flex;
    align-items: flex-start;
}
.pols-field__checkbox-label {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13px;
    color: var(--pols-text);
    cursor: pointer;
}
.pols-field__checkbox-label input[type="checkbox"] {
    margin-top: 3px;
}

.pols-auth-footer {
    margin-top: 24px;
    text-align: center;
    font-size: 12px;
    color: var(--pols-text-faint);
}
.pols-auth-footer a {
    color: var(--pols-text-muted);
}

/* Standalone "powered by" footer outside the auth card (login / forgot-password) */
.pols-auth-footer--standalone {
    margin-top: 32px;
}

/*──────────────────────────────────────────
 * Dashboard — session cards
 *────────────────────────────────────────*/
.pols-dashboard-filters {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.pols-dashboard-filters__search {
    flex: 1;
    min-width: 220px;
}

/* Status filter select — constrained width so it doesn't grow to fill the row */
.pols-dashboard-filters__status {
    max-width: 200px;
}

.pols-session-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 16px;
}

/* M3 expressive card: rests at scale(.99)/elev-1, expands to full + elev-2
   on hover with emphasized easing. Border kept transparent (1px) so the box
   size is unchanged; the sample card paints its accent on border-left. */
.pols-session-card {
    background: var(--m3-surface-container-lowest);
    border: 1px solid transparent;
    border-radius: var(--m3-shape-xl);
    padding: 22px;
    display: flex;
    flex-direction: column;
    box-shadow: var(--m3-elev-1);
    transform: scale(0.99);
    transition: transform var(--m3-duration-medium) var(--m3-easing-emphasized), box-shadow var(--m3-duration-medium) var(--m3-easing-emphasized);
}
.pols-session-card:hover {
    box-shadow: var(--m3-elev-2);
    transform: scale(1);
}

/* Sample/demo session keeps a distinguishing accent */
.pols-session-card--sample {
    border-left: 4px solid var(--pols-secondary-container);
}

.pols-session-card__header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 10px;
}

.pols-session-card__title {
    margin: 0;
    font: var(--md-sys-type-title-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-title-lg-ls);
    color: var(--m3-on-surface);
    word-break: break-word;
}

.pols-session-card__code {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.5px;
    background: var(--pols-surface-alt);
    border: 1px solid var(--pols-border);
    padding: 3px 8px;
    border-radius: var(--pols-radius-sm);
    color: var(--pols-text-muted);
    white-space: nowrap;
}

.pols-session-card__meta {
    display: flex;
    gap: 12px;
    margin-bottom: 12px;
    font-size: 12px;
    color: var(--pols-text-muted);
    flex-wrap: wrap;
}

.pols-session-card__actions {
    display: flex;
    gap: 8px;
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px solid var(--pols-border-soft);
    flex-wrap: wrap;
}

/*──────────────────────────────────────────
 * Status badges
 *────────────────────────────────────────*/
/* M3 chips-lite: shape-sm, label type, tonal backgrounds.
   active → success-container, draft → surface-container-high,
   closed → surface-container-highest + on-surface-variant. */
.pols-badge {
    display: inline-block;
    padding: 3px 8px;
    border-radius: var(--m3-shape-sm);
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border: 1px solid transparent;
}
.pols-badge--draft    { background: var(--m3-surface-container-high); color: var(--m3-on-surface-variant); }
.pols-badge--active   { background: var(--pols-success-container); color: var(--pols-on-success-container); }
.pols-badge--paused   { background: #fff4e5; color: #7a3e00; }
.pols-badge--closed   { background: var(--m3-surface-container-highest); color: var(--m3-on-surface-variant); }
.pols-badge--archived { background: var(--m3-surface-container-highest); color: var(--m3-outline); }

/*──────────────────────────────────────────
 * Empty state
 *────────────────────────────────────────*/
.pols-empty-state {
    text-align: center;
    padding: 60px 20px;
    background: var(--pols-surface);
    border: 1px dashed var(--pols-border);
    border-radius: var(--pols-radius);
}
.pols-empty-state h2 {
    color: var(--pols-text-muted);
}
.pols-empty-state p {
    color: var(--pols-text-muted);
    margin-bottom: 20px;
}

/*──────────────────────────────────────────
 * Loading states
 *────────────────────────────────────────*/
.pols-spinner {
    display: inline-block;
    width: 20px;
    height: 20px;
    border: 2px solid var(--pols-border);
    border-top-color: var(--pols-primary);
    border-radius: 50%;
    animation: pols-spin 0.8s linear infinite;
}
.pols-spinner--lg { width: 40px; height: 40px; border-width: 3px; }

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

.pols-loading {
    text-align: center;
    padding: 40px 20px;
    color: var(--pols-text-muted);
}

/* Inline variant injected by PolsApp.loading.show() — centered within
   whatever container element it is appended to. */
.pols-loading--inline {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 24px;
}

/*──────────────────────────────────────────
 * Modal — M3 dialog
 * shape-xxl container on surface-container-low, elev-3, 32% scrim,
 * entrance = scale .96→1 + fade with emphasized easing.
 *────────────────────────────────────────*/
.pols-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.32);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    animation: pols-fade-in var(--m3-duration-medium) var(--m3-easing-standard);
}
@keyframes pols-fade-in { from { opacity: 0; } }

.pols-modal {
    background: var(--m3-surface-container-low);
    border-radius: var(--m3-shape-xxl);
    box-shadow: var(--m3-elev-3);
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    overflow-y: auto;
    padding: 24px;
    animation: pols-dialog-in var(--m3-duration-medium) var(--m3-easing-emphasized);
}
@keyframes pols-dialog-in {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: scale(1); }
}

.pols-modal__header {
    margin-bottom: 16px;
}
.pols-modal__header h2 {
    font: var(--md-sys-type-headline-sm) var(--pols-font);
    letter-spacing: var(--md-sys-type-headline-sm-ls);
    color: var(--m3-on-surface);
}

.pols-modal__footer {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--m3-surface-container-high);
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* Scroll-lock applied to <body> while a full-screen overlay (e.g. the slide-type
   picker) is open, so the page behind the scrim cannot scroll. */
body.pols-modal-open {
    overflow: hidden;
}

/*──────────────────────────────────────────
 * Snackbar (M3) — built by the toast() helper in pols-app.js.
 * Inverse surface, shape-sm, bottom-center; success/error are signalled
 * by a leading 6px color bar instead of a full-surface color change.
 *────────────────────────────────────────*/
.pols-snackbar {
    display: flex;
    align-items: center;
    min-width: 240px;
    max-width: min(560px, calc(100vw - 32px));
    padding: 12px 16px;
    background: #2F3033;
    color: #F1F0F4;
    border-left: 6px solid transparent;
    border-radius: var(--m3-shape-sm);
    box-shadow: var(--m3-elev-3);
    font: var(--md-sys-type-body-md) var(--pols-font);
    letter-spacing: var(--md-sys-type-body-md-ls);
    animation: pols-snackbar-in var(--m3-duration-medium) var(--m3-easing-decelerate);
}
.pols-snackbar--success { border-left-color: var(--pols-success); }
.pols-snackbar--error   { border-left-color: var(--pols-danger); }
.pols-snackbar--warning { border-left-color: var(--pols-warning); }

@keyframes pols-snackbar-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/*──────────────────────────────────────────
 * Mobile nav toggle (hamburger)
 *────────────────────────────────────────*/
.pols-app-nav__toggle {
    display: none; /* hidden on desktop */
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    background: transparent;
    border: 0;
    padding: 8px;
    cursor: pointer;
    border-radius: var(--pols-radius-sm);
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
    flex-shrink: 0;
}
.pols-app-nav__toggle:hover {
    background: rgba(var(--pols-brand-seed-on-rgb), 0.08);
}

.pols-app-nav__toggle-bar {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--pols-brand-seed-on);
    border-radius: 2px;
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
}

/*──────────────────────────────────────────
 * Responsive
 *────────────────────────────────────────*/
@media (max-width: 720px) {
    .pols-app-nav__toggle { display: flex; }
    .pols-app-nav__inner { gap: 16px; }
    .pols-app-nav__title { font-size: 14px; }
    .pols-app-main { padding: 20px 16px; }
    .pols-page-header { flex-direction: column; align-items: flex-start; }
    .pols-session-grid { grid-template-columns: 1fr; }

    /* Nav drawer: hidden by default, slides down from under the header.
       Behaviour (JS toggle) untouched — only the panel surface is M3. */
    .pols-app-nav__links {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 2px;
        background: var(--m3-surface-container-low);
        border-radius: 0 0 var(--m3-shape-lg) var(--m3-shape-lg);
        padding: 8px 16px 12px;
        z-index: 99;
        box-shadow: var(--m3-elev-2);
    }
    .pols-app-nav__links.is-open {
        display: flex;
    }
    .pols-app-nav__link {
        padding: 12px 16px;
        border-radius: var(--m3-shape-full);
    }
}

/* ==========================================================================
   Phase 4d — Session editor
   ========================================================================== */

/*──────────────────────────────────────────
 * Back link
 *────────────────────────────────────────*/
.pols-editor-back {
    display: inline-block;
    font-size: 13px;
    color: var(--pols-text-muted);
    margin-bottom: 12px;
}
.pols-editor-back:hover {
    color: var(--pols-primary);
    text-decoration: none;
}

/*──────────────────────────────────────────
 * Editor header
 *────────────────────────────────────────*/
.pols-editor-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 24px;
}

.pols-editor-header__text {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.pols-editor-header__text h1 {
    margin-bottom: 4px;
}

.pols-editor-header__text p.description {
    font-size: 13px;
    color: var(--pols-text-muted);
    max-width: 60ch;
    margin: 0;
}

.pols-editor-header__actions {
    display: flex;
    gap: 10px;
    flex-shrink: 0;
}

/*──────────────────────────────────────────
 * Status row
 *────────────────────────────────────────*/
.pols-editor-status {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: center;
    margin: 8px 0 10px;
}

.pols-editor-status__item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.pols-editor-status__label {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.05em;
    color: var(--pols-text-muted);
}

/*──────────────────────────────────────────
 * Content status badges
 *────────────────────────────────────────*/
.pols-badge--content-publish    { background: var(--pols-success-container); color: var(--pols-on-success-container); }
.pols-badge--content-draft      { background: var(--m3-surface-container-high); color: var(--m3-on-surface-variant); }
.pols-badge--content-auto-draft { background: var(--m3-surface-container-high); color: var(--m3-on-surface-variant); }
.pols-badge--content-pending    { background: #fff4e0; color: #8a5a00; }
.pols-badge--content-future     { background: #e6f0fb; color: #1e4d8a; }
.pols-badge--content-private    { background: #efeaf7; color: #5a3a8a; }
.pols-badge--content-trash      { background: #fbeaea; color: #8a1e1e; } /* danger tint preserved */

/*──────────────────────────────────────────
 * Slide list container
 *────────────────────────────────────────*/
.pols-editor-slides {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 24px;
}

/*──────────────────────────────────────────
 * Slide card
 *────────────────────────────────────────*/
.pols-editor-slide {
    background: var(--m3-surface-container-lowest);
    border: 1px solid transparent; /* size-preserving; tonal surface replaces the hairline */
    border-radius: var(--m3-shape-lg);
    box-shadow: var(--m3-elev-1);
    overflow: hidden; /* expanded body's tonal well stays inside the rounded card */
}

.pols-editor-slide__header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 20px;
    cursor: pointer;
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-slide__header:hover {
    background: var(--m3-state-hover);
}

/*──────────────────────────────────────────
 * Phase 4d — Drag-and-drop reorder (Sortable.js)
 *────────────────────────────────────────*/
.pols-editor-slide__drag {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    min-width: 20px;
    flex-shrink: 0;
    color: var(--pols-text-muted);
    cursor: grab;
    user-select: none;
    font-size: 14px;
    line-height: 1;
    /* Small negative letter-spacing makes the two vertical ellipses read
       as a 2x3 grip of dots. */
    letter-spacing: -2px;
    transition: color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-slide__drag:hover {
    color: var(--pols-primary);
    background: var(--m3-state-hover);
    border-radius: var(--m3-shape-full);
}
.pols-editor-slide__drag:active,
.pols-editor-slide.sortable-chosen .pols-editor-slide__drag {
    cursor: grabbing;
}

/* Ghost: placeholder left behind while dragging. Fade it so the item
   clearly reads as "somewhere else" right now. */
.pols-editor-slide.sortable-ghost {
    opacity: 0.35;
    background: var(--pols-surface-alt);
}

/* Chosen: the card the user is actively dragging. Subtle elevation. */
.pols-editor-slide.sortable-chosen {
    box-shadow: var(--m3-elev-3);
}

/* Drag: the moving clone. Slight rotation gives a "picked up" feel and
   forces it above siblings during the flight. */
.pols-editor-slide.sortable-drag {
    opacity: 0.95;
    transform: rotate(1deg);
    z-index: 100;
}

.pols-editor-slide__order {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 28px;
    padding: 0 6px;
    background: var(--pols-surface-alt);
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius-sm);
    font-size: 12px;
    font-weight: 500;
    color: var(--pols-text-muted);
    flex-shrink: 0;
}

.pols-editor-slide__icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--pols-text-muted);
}

.pols-editor-slide__title-wrap {
    flex: 1;
    min-width: 0;
}

.pols-editor-slide__title {
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-editor-slide__type {
    font-size: 12px;
    color: var(--pols-text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.pols-editor-slide__caret {
    flex-shrink: 0;
    color: var(--pols-text-muted);
    border-radius: var(--m3-shape-full);
    transition: transform var(--m3-duration-short) var(--m3-easing-standard),
                background-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-slide__header:hover .pols-editor-slide__caret {
    background: var(--m3-state-hover);
}
.pols-editor-slide.is-expanded .pols-editor-slide__caret {
    transform: rotate(180deg);
}

.pols-editor-slide__actions {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}

/* Expanded body = tonal well (container-low) holding an inset shape-md
   panel (the form itself, back on container-lowest) so the form-vs-card
   hierarchy is visible at a glance. */
.pols-editor-slide__body {
    display: none;
    border-top: 1px solid var(--m3-surface-container-high);
    padding: 12px;
    background: var(--m3-surface-container-low);
}
.pols-editor-slide.is-expanded .pols-editor-slide__body {
    display: block;
}

/*──────────────────────────────────────────
 * Form grid inside slide body
 *────────────────────────────────────────*/
.pols-editor-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    background: var(--m3-surface-container-lowest);
    border-radius: var(--m3-shape-md);
    padding: 16px;
}

.pols-editor-form__row {
    display: flex;
    gap: 12px;
}

.pols-editor-form__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
}

.pols-editor-form__field label {
    font-size: 13px;
    font-weight: 500;
    color: var(--pols-text);
}

.pols-editor-form__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--pols-border);
}

/*──────────────────────────────────────────
 * Option rows + form placeholder
 *────────────────────────────────────────*/
.pols-editor-form__options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 8px;
}

.pols-editor-form__option-row {
    display: flex;
    gap: 8px;
    align-items: center;
}
.pols-editor-form__option-row .pols-input {
    flex: 1;
}
.pols-editor-form__option-row [data-form-action="remove-option"] {
    flex-shrink: 0;
    min-width: 32px;
    padding: 4px 8px;
}

.pols-editor-form__placeholder {
    padding: 16px;
    background: var(--pols-surface-alt);
    border: 1px dashed var(--pols-border);
    border-radius: var(--pols-radius-sm);
    text-align: center;
    color: var(--pols-text-muted);
    font-size: 13px;
}
.pols-editor-form__placeholder p {
    margin: 0;
}

/*──────────────────────────────────────────
 * Phase 4d — Toolbar + type picker
 *────────────────────────────────────────*/
.pols-editor-toolbar {
    display: flex;
    justify-content: flex-start;
    gap: 12px;
    margin-bottom: 16px;
    position: relative;
}

/* The slide-type picker opens as a near-full-screen modal overlay (the element
   itself is the scrim). It reuses the M3 dialog tokens + pols-fade-in /
   pols-dialog-in animations defined in the .pols-modal block above. */
.pols-editor-type-picker {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.32);
    animation: pols-fade-in var(--m3-duration-medium) var(--m3-easing-standard);
}
.pols-editor-type-picker[hidden] {
    display: none;
}

.pols-editor-type-picker__panel {
    display: flex;
    flex-direction: column;
    width: min(1100px, 94vw);
    max-height: 90vh;
    background: var(--m3-surface-container-low);
    border-radius: var(--m3-shape-xxl);
    box-shadow: var(--m3-elev-3);
    padding: 24px;
    animation: pols-dialog-in var(--m3-duration-medium) var(--m3-easing-emphasized);
}

.pols-editor-type-picker__header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 16px;
}

.pols-editor-type-picker__title {
    font: var(--md-sys-type-headline-sm) var(--pols-font);
    letter-spacing: var(--md-sys-type-headline-sm-ls);
    color: var(--m3-on-surface);
    margin: 0;
}

.pols-editor-type-picker__close {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    font-size: 26px;
    line-height: 1;
    background: transparent;
    border: 0;
    border-radius: var(--m3-shape-full);
    color: var(--m3-on-surface-variant);
    cursor: pointer;
    transition: background-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-type-picker__close:hover {
    background: var(--m3-state-hover);
}
.pols-editor-type-picker__close:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}

.pols-editor-type-picker__grid {
    flex: 1 1 auto;
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}

.pols-editor-type-picker__tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    min-height: 150px;
    padding: 20px 16px;
    background: var(--m3-surface-container-lowest);
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-lg);
    cursor: pointer;
    font: var(--md-sys-type-label-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-label-lg-ls);
    text-align: center;
    color: var(--m3-on-surface);
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard), background-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-type-picker__tile:hover {
    border-color: var(--pols-primary);
    background: var(--m3-state-hover);
}
/* Selection moment (tiles create the slide on click — no persistent state) */
.pols-editor-type-picker__tile:active:not(:disabled) {
    background: var(--pols-secondary-container);
    border-color: transparent;
    color: var(--pols-on-secondary-container);
}
.pols-editor-type-picker__tile:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}
.pols-editor-type-picker__tile:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.pols-editor-type-picker__tile .pols-slide-icon {
    width: 36px;
    height: 36px;
    color: var(--pols-primary);
}
.pols-editor-type-picker__tile svg {
    width: 36px;
    height: 36px;
    color: var(--pols-primary);
}
.pols-editor-type-picker__tile-label {
    font-size: 16px;
    font-weight: 500;
}
.pols-editor-type-picker__tile-desc {
    font-size: 13px;
    color: var(--pols-text-muted);
    line-height: 1.4;
}

/* Tablet: 3 columns (must precede the 720px rule so it does not override it). */
@media (max-width: 1024px) {
    .pols-editor-type-picker__grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/*──────────────────────────────────────────
 * Editor responsive
 *────────────────────────────────────────*/
@media (max-width: 720px) {
    .pols-editor-header {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    .pols-editor-header__actions {
        align-self: stretch;
    }
    .pols-editor-header__actions .pols-btn,
    .pols-editor-header > .pols-btn {
        width: 100%;
    }
    .pols-editor-slide__header {
        flex-wrap: wrap;
    }
    .pols-editor-slide__title {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
    }
    .pols-editor-slide__actions {
        width: 100%;
        margin-top: 4px;
    }
    .pols-editor-form__row {
        flex-direction: column;
    }
    .pols-editor-type-picker {
        padding: 12px;
    }
    .pols-editor-type-picker__panel {
        width: 100%;
        max-height: 94vh;
        padding: 16px;
    }
    .pols-editor-type-picker__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .pols-editor-type-picker__grid {
        grid-template-columns: 1fr;
    }
}

/* ==========================================================================
   Phase 4d — Editor forms cleanup
   ==========================================================================
   Append-only block covering classes that accumulated without CSS across
   Pieces 9–22.5. No existing rules are modified; every new selector is
   either a net-new class, a descendant of a net-new class, or uses a data-
   attribute selector (for the hotspot radius region, which uses a data-
   attribute rather than a class). Tokens reused from the :root block; no
   new tokens introduced, no importance overrides, no animation.
   ========================================================================== */

/*──────────────────────────────────────────
 * Radio groups (true_false correct answer)
 *────────────────────────────────────────*/
.pols-editor-form__radio-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
}

.pols-editor-form__radio-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    font-size: 14px;
    color: var(--pols-text);
    cursor: pointer;
    user-select: none;
}

.pols-editor-form__radio-label input[type="radio"] {
    margin: 0;
    cursor: pointer;
}

/*──────────────────────────────────────────
 * Kennischeck sub-question repeater
 *
 * Each sub-question renders as a card-within-the-card: tinted
 * background, border, with a header row (label + remove button),
 * the statement input, and a nested options list. The nested
 * options are indented with a left border so their "belongs to
 * this sub-question" relationship reads at a glance. Each option
 * row has a radio (mark-as-correct) and the option text input.
 *
 * Field-shape note: the brief originally assumed a separate
 * .pols-editor-form__question-text wrapper and a dedicated
 * .pols-editor-form__question-correct element; Piece 22.5's
 * corrected shape uses a bare statement input and per-option
 * radios instead, so neither class exists in the markup and
 * both are intentionally not styled.
 *────────────────────────────────────────*/
.pols-editor-form__questions {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 12px;
}

.pols-editor-form__question-row {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
    background: var(--pols-surface-alt);
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius-sm);
}

.pols-editor-form__question-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.pols-editor-form__question-header label {
    margin: 0;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.05em;
    color: var(--pols-text-muted);
}

.pols-editor-form__question-options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
    padding-left: 12px;
    border-left: 2px solid var(--pols-border);
}

.pols-editor-form__question-option-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pols-editor-form__question-option-row .pols-input {
    flex: 1;
    min-width: 0;
}

.pols-editor-form__question-option-row input[type="radio"] {
    flex-shrink: 0;
    margin: 0;
    cursor: pointer;
}

/*──────────────────────────────────────────
 * Matching pairs repeater
 *
 * Single row on desktop: [left input] [↔] [right input] [×].
 * Mobile stacks the two text inputs with the separator glyph
 * centered between them; the remove button wraps to the next
 * line so it still has a tap-target.
 *────────────────────────────────────────*/
.pols-editor-form__pairs {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 8px;
}

.pols-editor-form__pair-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pols-editor-form__pair-row .pols-input {
    flex: 1;
    min-width: 0;
}

.pols-editor-form__pair-link {
    flex-shrink: 0;
    font-size: 18px;
    color: var(--pols-text-faint);
    user-select: none;
}

/*──────────────────────────────────────────
 * Image field (shared across all slide types with image upload)
 *
 * Piece 22 applied most layout rules via inline styles on the
 * JS template; those inline styles win over the rules below and
 * are the load-bearing source. The rules here exist as a
 * defensive fallback for future inline-style removal plus the
 * visuals that were never inlined (empty-state dashed border,
 * muted hint text, bordered thumbnail).
 *
 * The hotspot target overlay and [data-slide-image-wrapper]
 * div are fully inline-styled in renderFormHotspot — intentionally
 * not styled here to avoid a second source of truth for the
 * click-to-place math.
 *────────────────────────────────────────*/
.pols-editor-form__image-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 8px;
}

.pols-editor-form__image-status {
    font-size: 12px;
    color: var(--pols-text-muted);
}

.pols-editor-form__image-preview {
    display: inline-block;
    max-width: 100%;
}

.pols-editor-form__image-preview img {
    display: block;
    max-width: 240px;
    max-height: 180px;
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius-sm);
}

.pols-editor-form__image-empty {
    padding: 12px;
    background: var(--pols-surface-alt);
    border: 1px dashed var(--pols-border);
    border-radius: var(--pols-radius-sm);
    font-size: 12px;
    color: var(--pols-text-muted);
    text-align: center;
}

.pols-editor-form__image-empty p {
    margin: 0;
}

.pols-editor-form__image-empty-text {
    margin: 0;
    color: var(--pols-muted);
    font-size: 12px;
}

.pols-editor-form__image-hint {
    margin: 0 0 8px 0;
    font-size: 12px;
    color: var(--pols-text-muted);
}

/*──────────────────────────────────────────
 * Hotspot radius slider region
 *
 * The region uses a data-attribute (data-hotspot-radius-field)
 * rather than a class, and is already wrapped in a
 * .pols-editor-form__field so its column layout comes from
 * there. These rules only handle the range-input bleedthrough
 * (the range accidentally inherits .pols-input's padding and
 * border) and the percentage label next to it.
 *────────────────────────────────────────*/
[data-hotspot-radius-field] input[type="range"] {
    width: 100%;
    max-width: 300px;
    padding: 0;
    background: transparent;
    border: none;
    box-shadow: none;
}

[data-hotspot-radius-field] [data-hotspot-radius-label] {
    font-size: 12px;
    color: var(--pols-text-muted);
}

/*──────────────────────────────────────────
 * Editor forms cleanup — responsive
 *
 * Matches the existing 720px breakpoint used by the rest of
 * the editor block above.
 *────────────────────────────────────────*/
@media (max-width: 720px) {
    .pols-editor-form__radio-group {
        gap: 12px;
    }
    .pols-editor-form__question-row {
        padding: 10px;
    }
    .pols-editor-form__question-options {
        padding-left: 10px;
    }
    .pols-editor-form__pair-row {
        flex-wrap: wrap;
    }
    .pols-editor-form__pair-row .pols-input {
        flex: 1 0 100%;
    }
    .pols-editor-form__pair-link {
        flex: 1 0 100%;
        text-align: center;
    }
}

/* ==========================================================================
   Phase 4g — Shell polish
   ========================================================================== */

/*──────────────────────────────────────────
 * Skip-to-content link (a11y)
 * Standard keyboard-accessible skip link: hidden off-screen until focused.
 *────────────────────────────────────────*/
.pols-skip-link {
    position: absolute;
    top: -100px;
    left: 0;
    padding: 8px 16px;
    background: var(--pols-primary);
    color: var(--pols-primary-on);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    z-index: 1000;
    border-radius: 0 0 var(--pols-radius-sm) 0;
    transition: top var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-skip-link:focus {
    top: 0;
    outline: 2px solid #fff;
    outline-offset: -2px;
}
/* Colour only, at the specificity of `.pols-app a:not(.pols-btn)` (0,2,1),
   which otherwise wins and draws the link text in the primary on its own
   primary fill (1:1). Kept apart from the rule above so `top` stays at
   (0,1,0) and the :focus reveal still beats it. */
.pols-app a.pols-skip-link {
    color: var(--pols-primary-on);
}

/*──────────────────────────────────────────
 * Back link — reusable "← Label" above page titles
 * Used by: editor.php ("← Sessies"), Phase 5 results.php ("← {title}")
 *────────────────────────────────────────*/
.pols-back-link {
    display: inline-block;
    font-size: 13px;
    color: var(--pols-text-muted);
    text-decoration: none;
    margin-bottom: 8px;
}
.pols-back-link:hover {
    color: var(--pols-primary);
    text-decoration: underline;
}

/*──────────────────────────────────────────
 * Branded error pages (404 / 403)
 *────────────────────────────────────────*/

.pols-error-page {
    text-align: center;
    padding: 80px 24px 40px;
    max-width: 480px;
    margin: 0 auto;
}

.pols-error-page__icon {
    font-size: 72px;
    font-weight: 700;
    color: var(--pols-border);
    line-height: 1;
    margin-bottom: 16px;
    letter-spacing: -2px;
}

.pols-error-page h1 {
    font-size: 28px;
    margin-bottom: 12px;
}

.pols-error-page p {
    color: var(--pols-text-muted);
    margin-bottom: 28px;
}

/* Dashboard scope toggle — M3 filter chips. Selected chip = tonal
   secondary-container with the border hidden; unselected = outlined. */
.pols-dashboard-scope {
    display: inline-flex;
    gap: 8px;
    margin: 0 0 16px 0;
}
.pols-dashboard-scope__btn {
    appearance: none;
    background: transparent;
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-sm);
    padding: 7px 16px;
    font: var(--md-sys-type-label-lg) var(--pols-font);
    letter-spacing: var(--md-sys-type-label-lg-ls);
    color: var(--m3-on-surface-variant);
    cursor: pointer;
    transition: background-color var(--m3-duration-short) var(--m3-easing-standard),
                border-color     var(--m3-duration-short) var(--m3-easing-standard),
                color            var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-dashboard-scope__btn:hover {
    background: var(--m3-state-hover);
}
.pols-dashboard-scope__btn:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}
.pols-dashboard-scope__btn.is-active {
    background: var(--pols-secondary-container);
    border-color: transparent;
    color: var(--pols-on-secondary-container);
}

/* Phase 4 cleanup — dual badge labels on dashboard cards */
.pols-session-card__badge-label {
    font-size: 11px;
    color: var(--pols-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-right: 2px;
}

/* Phase 4 cleanup — inline editable session title */
.pols-editor-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: text;
    padding: 2px 6px;
    margin: -2px -6px;
    border-radius: var(--m3-shape-sm);
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-title:hover,
.pols-editor-title:focus-visible {
    background: var(--m3-state-hover);
    outline: none;
}
.pols-editor-title__pencil {
    font-size: 0.7em;
    opacity: 0;
    color: var(--pols-muted);
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-editor-title:hover .pols-editor-title__pencil,
.pols-editor-title:focus-visible .pols-editor-title__pencil {
    opacity: 1;
}
.pols-editor-title.is-editing {
    background: transparent;
    padding: 0;
    margin: 0;
}
.pols-editor-title__input {
    font: inherit;
    font-weight: inherit;
    color: inherit;
    width: 100%;
    max-width: 640px;
    padding: 4px 8px;
    border: 2px solid var( --pols-primary, #1a6e7a );
    border-radius: var(--m3-shape-sm);
    background: var( --pols-surface, #fff );
}
.pols-editor-title__input:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba( 26, 110, 122, 0.15 );
}

/*──────────────────────────────────────────
 * Phase 5a — Session results page
 *────────────────────────────────────────*/

/* Page header (back-link, title, actions, snapshot tabs) */
.pols-results-header {
    max-width: 1200px;
    margin: 0 auto;
    padding: 24px 24px 0;
}

.pols-results-header__top {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    margin: 8px 0 16px;
}

.pols-results-header__title {
    flex: 1;
    font-size: 22px;
    margin-bottom: 0;
}

.pols-results-header__actions {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

/* Snapshot tab bar */
.pols-results-snapshot-bar {
    display: flex;
    gap: 0;
    border-bottom: 2px solid var(--pols-border);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin-bottom: 0;
}

.pols-results-snapshot-btn {
    padding: 8px 18px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    color: var(--pols-text-muted);
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--m3-duration-short) var(--m3-easing-standard), border-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-results-snapshot-btn:hover {
    color: var(--pols-text);
}
.pols-results-snapshot-btn.is-active {
    color: var(--pols-primary);
    border-bottom-color: var(--pols-primary);
}

/* Two-column body: slides list + leaderboard sidebar */
.pols-results-body {
    max-width: 1200px;
    margin: 0 auto;
    padding: 24px;
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    align-items: start;
}
@media (min-width: 1024px) {
    .pols-results-body {
        grid-template-columns: 1fr 280px;
    }
}

.pols-results-slides {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

/* Slide result card */
.pols-results-slide-card {
    background: var(--pols-surface);
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius);
    overflow: hidden;
}

.pols-results-slide-card__header {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--pols-border-soft);
}

.pols-results-slide-card__num {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    min-width: 28px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--pols-primary) 12%, transparent);
    color: var(--pols-primary);
    font-size: 12px;
    font-weight: 700;
}

.pols-results-slide-card__meta {
    flex: 1;
    min-width: 0;
}

.pols-results-slide-card__title {
    font-size: 15px;
    font-weight: 500;
    margin-bottom: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-results-slide-card__count {
    font-size: 12px;
    color: var(--pols-text-muted);
}

.pols-results-slide-card__chart {
    padding: 16px 20px;
}

.pols-results-slide-card__empty {
    color: var(--pols-text-faint);
    font-size: 13px;
    margin: 0;
}

/* Tally bars (choice types — MC / quiz / true_false) */
.pols-results-tally {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pols-results-tally__item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--pols-radius-sm);
    position: relative;
    min-height: 32px;
}

/* CSS-variable-driven fill bar behind the label */
.pols-results-tally__track {
    position: absolute;
    inset: 0;
    width: var(--pct, 0%);
    background: color-mix(in srgb, var(--pols-primary) 12%, transparent);
    border-radius: var(--pols-radius-sm);
    pointer-events: none;
    transition: width var(--m3-duration-long) var(--m3-easing-decelerate);
}

.pols-results-tally__item.is-correct .pols-results-tally__track {
    background: color-mix(in srgb, var(--pols-success) 15%, transparent);
}

.pols-results-tally__label {
    flex: 1;
    font-size: 13px;
    position: relative;
    z-index: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-results-tally__item.is-correct .pols-results-tally__label {
    color: var(--pols-success);
    font-weight: 500;
}

.pols-results-tally__count {
    font-size: 12px;
    color: var(--pols-text-muted);
    white-space: nowrap;
    position: relative;
    z-index: 1;
}

/* Average stat (scale / likert / numeric) */
.pols-results-avg {
    font-size: 14px;
    color: var(--pols-text-muted);
    margin: 0;
}
.pols-results-avg strong {
    color: var(--pols-text);
    font-size: 20px;
    font-weight: 700;
}

/* Word cloud */
.pols-results-words {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: baseline;
}
.pols-results-word {
    color: var(--pols-primary);
    line-height: 1.3;
}

/* Text feed (open_text / qa / reflection) */
.pols-results-texts {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pols-results-texts li {
    padding: 8px 10px;
    background: var(--pols-surface-alt);
    border-left: 3px solid var(--pols-border);
    border-radius: 0 var(--pols-radius-sm) var(--pols-radius-sm) 0;
    font-size: 13px;
    color: var(--pols-text);
}

/* Ranking (ordered list) */
.pols-results-ranking {
    margin: 0;
    padding: 0 0 0 20px;
    font-size: 13px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Leaderboard sidebar */
.pols-results-leaderboard {
    background: var(--pols-surface);
    border: 1px solid var(--pols-border);
    border-radius: var(--pols-radius);
    padding: 20px;
    align-self: start;
    position: sticky;
    top: calc(var(--pols-nav-height) + 24px);
}

.pols-results-leaderboard__title {
    margin-bottom: 16px;
    font-size: 16px;
}

.pols-results-leaderboard__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
}

.pols-results-leaderboard__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--pols-border-soft);
}
.pols-results-leaderboard__item:last-child {
    border-bottom: none;
}

.pols-results-leaderboard__rank {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    min-width: 24px;
    border-radius: 50%;
    background: var(--pols-bg);
    font-size: 11px;
    font-weight: 700;
    color: var(--pols-text-muted);
}
.pols-results-leaderboard__item:nth-child(1) .pols-results-leaderboard__rank {
    background: #ffd700; color: #5a4800;
}
.pols-results-leaderboard__item:nth-child(2) .pols-results-leaderboard__rank {
    background: #c0c0c0; color: #444;
}
.pols-results-leaderboard__item:nth-child(3) .pols-results-leaderboard__rank {
    background: #cd7f32; color: #1b2733; /* white measured 3.14:1 */
}

.pols-results-leaderboard__name {
    flex: 1;
    font-size: 13px;
    font-weight: 500;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-results-leaderboard__score {
    font-size: 13px;
    font-weight: 700;
    color: var(--pols-primary);
}

/*──────────────────────────────────────────
 * Phase 5a-3 — Results page scaffold
 *────────────────────────────────────────*/

/* Page-level background override via body class */
.pols-results {
    background: var(--pols-surface);
}

/* Meta row: date · mode badge · participant count · status badge · picker */
.pols-results-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    font-size: 14px;
    color: var(--pols-text-muted);
    margin-top: 8px;
    margin-bottom: 16px;
}

.pols-results-meta__date {
    color: var(--pols-text-muted);
}

.pols-results-meta__action + .pols-results-meta__action { margin-left: 4px; }

.pols-results-meta__badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: var(--m3-shape-md);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    background: var(--pols-border);
    color: var(--pols-text-muted);
}

.pols-results-meta__badge--mode {
    background: rgba(26, 110, 122, 0.10);
    color: var(--pols-primary);
}

.pols-results-meta__badge--participants {
    background: rgba(0, 0, 0, 0.06);
}

.pols-results-meta__badge--status.pols-results-meta__badge--closed {
    background: rgba(46, 125, 50, 0.12);
    color: #1a6e2a;
}

.pols-results-meta__badge--status.pols-results-meta__badge--active {
    background: rgba(220, 38, 38, 0.10);
    color: #b91c1c;
}

.pols-results-meta__badge--status.pols-results-meta__badge--paused,
.pols-results-meta__badge--status.pols-results-meta__badge--draft {
    background: rgba(0, 0, 0, 0.06);
}

.pols-results-snapshot-picker {
    margin-left: auto;
    max-width: 200px;
}

/* Slide cards grid — overrides the Phase 5a-1 flex column */
.pols-results-slides {
    display: grid;
    gap: 24px;
    max-width: 800px;
    margin: 0 auto 40px;
    padding: 0 24px;
}

/* Individual result card */
.pols-result-card {
    background: #fff;
    border-radius: var(--m3-shape-md);
    padding: 24px;
    box-shadow: var(--m3-elev-1);
}

.pols-result-card__header {
    display: flex;
    align-items: baseline;
    gap: 16px;
    margin-bottom: 16px;
}

.pols-result-card__num {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--pols-primary);
    color: var(--pols-primary-on);
    font-size: 12px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

.pols-result-card__title {
    flex: 1;
    font-size: 18px;
    font-weight: 500;
    line-height: 1.3;
    margin: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-result-card__type {
    font-size: 12px;
    color: var(--pols-text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.pols-result-card__count {
    font-size: 12px;
    color: var(--pols-text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.pols-result-render {
    min-height: 240px;
    position: relative;
}

.pols-result-card__order {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--pols-primary);
    color: var(--pols-primary-on);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 500;
    flex-shrink: 0;
}

.pols-result-card__desc {
    color: var(--pols-text-muted);
    font-size: 14px;
    margin-bottom: 12px;
    line-height: 1.5;
}

.pols-result-stats {
    margin-top: 16px;
    font-size: 14px;
    color: var(--pols-text-muted);
    text-align: center;
}

.pols-result-stats strong {
    color: var(--pols-text);
    font-weight: 500;
}

/* Word cloud container (light theme) */
.pols-wordcloud {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 12px;
    padding: 20px;
    min-height: 120px;
}

/* pols.css sets background:rgba(255,255,255,0.1) on .pols-word for the
   dark presenter view; override to a subtle neutral for white backgrounds.
   PolsCharts sets el.style.color directly so the inline style wins. */
.pols-wordcloud--light .pols-word {
    background: rgba(0, 0, 0, 0.05);
}

/* Override dark-theme colours from pols.css for the numeric HTML panel */
.pols-results .pols-numeric-results {
    background: transparent;
}

.pols-results .pols-numeric-big {
    color: var(--pols-text);
}

.pols-results .pols-numeric-label {
    color: var(--pols-text-muted);
}

/*──────────────────────────────────────────
 * Phase 5a-9 — Text feed (open_text / qa / reflection)
 *────────────────────────────────────────*/

.pols-text-feed {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0;
}

.pols-text-feed__entry {
    background: var(--pols-bg);
    border-radius: var(--m3-shape-sm);
    padding: 10px 14px;
}

.pols-text-feed__body {
    font-size: 0.95rem;
    color: var(--pols-text);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

.pols-text-feed__meta {
    font-size: 0.75rem;
    color: var(--pols-text-muted);
    margin-top: 4px;
}

.pols-text-feed__more {
    margin-top: 4px;
}

.pols-text-feed__more > summary {
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--pols-primary);
    padding: 4px 0;
    list-style: none;
    user-select: none;
}

.pols-text-feed__more > summary::-webkit-details-marker {
    display: none;
}

.pols-text-feed__more[open] > summary {
    margin-bottom: 8px;
}

.pols-result-empty {
    font-style: italic;
    color: var(--pols-text-muted);
    font-size: 0.9rem;
    text-align: center;
    padding: 16px 0;
    margin: 0;
}

/*──────────────────────────────────────────
 * Phase 5a-14 — Print stylesheet (results page)
 *────────────────────────────────────────*/

@media print {
    @page {
        size: A4;
        margin: 18mm 15mm;
    }

    body.pols-results .pols-app-nav,
    body.pols-results .pols-app-footer,
    body.pols-results .pols-back-link,
    body.pols-results .pols-skip-link,
    body.pols-results #pols-snapshot-picker,
    body.pols-results #pols-compare-toggle,
    body.pols-results #pols-export-csv-btn,
    body.pols-results .pols-results-meta__action,
    body.pols-results #pols-results-loading,
    body.pols-results #pols-results-empty {
        display: none !important;
    }

    /* Preserve brand colors on printed output (chart fills, badges, etc.). */
    body.pols-results,
    body.pols-results * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    body.pols-results {
        background: white !important;
        color: #000 !important;
        font-size: 11pt;
    }

    body.pols-results main.pols-app-main {
        padding: 0 !important;
        max-width: 100% !important;
    }

    body.pols-results .pols-results-header {
        margin-bottom: 12mm;
    }

    body.pols-results .pols-results-header h1 {
        break-after: avoid;
    }

    /* Each slide card starts on a fresh page; keep header + chart together. */
    body.pols-results .pols-result-card {
        page-break-before: always;
        break-before: page;
        page-break-inside: avoid;
        break-inside: avoid;
        box-shadow: none !important;
        border: 1px solid #cfcfcf;
        margin: 0 0 8mm;
    }

    /* Leaderboard and focus-areas are their own pages. */
    body.pols-results .pols-results-leaderboard,
    body.pols-results .pols-results-focus-areas,
    body.pols-results .pols-results-recap {
        page-break-after: always;
        break-after: page;
        page-break-inside: avoid;
        break-inside: avoid;
    }

    /* Chart.js canvases: constrain to printable width, let height follow.
       PolsCharts.resizeAll() is called from the beforeprint listener so
       each chart re-rasterises at the new width before the print dialog
       captures it. */
    body.pols-results .pols-result-card canvas {
        max-width: 100% !important;
        max-height: 110mm !important;
        height: auto !important;
    }

    /* Hint to the browser to keep headings with the following content. */
    body.pols-results h1,
    body.pols-results h2,
    body.pols-results h3 {
        break-after: avoid;
    }
}

/*──────────────────────────────────────────
 * Phase 5e.2 — Mode-aware results enrichments
 *────────────────────────────────────────*/

/* ── Leaderboard sidebar (competitief) — reuse Phase 5a rules, just unhidden ── */

/* Ensure leaderboard is not too narrow when shown full-width on a narrow screen */
.pols-results-leaderboard {
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 24px;
}

/* ── Focus-areas callout (educatief) ─────────────────────────────────────────── */

.pols-results-focus-areas {
    max-width: 800px;
    margin: 0 auto 24px;
    padding: 0 24px;
}

.pols-focus-areas__title {
    font-size: 18px;
    font-weight: 700;
    margin: 0 0 6px;
    color: var(--pols-text);
}

.pols-focus-areas__intro {
    font-size: 14px;
    color: var(--pols-text-muted);
    margin: 0 0 16px;
    line-height: 1.5;
}

.pols-focus-areas__empty {
    font-size: 14px;
    font-style: italic;
    color: var(--pols-text-muted);
    margin: 0;
}

.pols-focus-areas__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.pols-focus-area-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: #fff;
    border-radius: var(--m3-shape-md);
    padding: 14px 18px;
    border-left: 4px solid var(--pols-secondary);
    box-shadow: var(--m3-elev-1);
}

.pols-focus-area-item__num {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--pols-secondary);
    color: var(--pols-secondary-on);
    font-size: 12px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

.pols-focus-area-item__title {
    flex: 1;
    font-size: 14px;
    font-weight: 500;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pols-focus-area-item__pct {
    font-size: 20px;
    font-weight: 700;
    color: var(--pols-secondary);
    flex-shrink: 0;
    line-height: 1;
}

.pols-focus-area-item__label {
    font-size: 12px;
    color: var(--pols-text-muted);
    flex-shrink: 0;
}

/* ── Response-time stat badge per slide (competitief) ─────────────────────────── */

.pols-result-rt-stat {
    margin-top: 12px;
    padding: 6px 10px;
    background: color-mix(in srgb, var(--pols-primary) 8%, transparent);
    border-radius: var(--m3-shape-sm);
    font-size: 13px;
    color: var(--pols-text-muted);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.pols-result-rt-stat__label {
    font-size: 12px;
    color: var(--pols-text-muted);
}

.pols-result-rt-stat strong {
    color: var(--pols-primary);
    font-weight: 700;
}

/* ── Slide-grid recap (interactief) ──────────────────────────────────────────── */

.pols-results-recap {
    max-width: 800px;
    margin: 0 auto 24px;
    padding: 0 24px;
}

.pols-recap-grid__title {
    font-size: 18px;
    font-weight: 700;
    margin: 0 0 16px;
    color: var(--pols-text);
}

.pols-recap-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 10px;
}

.pols-recap-grid__item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: #fff;
    border-radius: var(--m3-shape-md);
    padding: 14px 16px;
    text-decoration: none;
    color: inherit;
    border: 2px solid transparent;
    box-shadow: var(--m3-elev-1);
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard), box-shadow var(--m3-duration-short) var(--m3-easing-standard);
    cursor: pointer;
}

.pols-recap-grid__item:hover,
.pols-recap-grid__item:focus-visible {
    border-color: var(--pols-primary);
    box-shadow: var(--m3-elev-2);
    outline: none;
}

.pols-recap-grid__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--pols-primary);
    color: var(--pols-primary-on);
    font-size: 11px;
    font-weight: 700;
    flex-shrink: 0;
    margin-bottom: 4px;
}

.pols-recap-grid__title-text {
    font-size: 13px;
    font-weight: 500;
    line-height: 1.4;
    flex: 1;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.pols-recap-grid__count {
    font-size: 11px;
    color: var(--pols-text-muted);
    margin-top: 2px;
}

/* ── Highlight flash when scrolled-to from the recap grid ────────────────────── */

@keyframes pols-result-highlight {
    0%   { outline-color: var(--pols-primary); }
    60%  { outline-color: var(--pols-primary); }
    100% { outline-color: transparent; }
}

.pols-result-card--highlight {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
    animation: pols-result-highlight 2s var(--md-sys-motion-easing-standard) forwards;
}

/* ── Print: hide focus-areas and recap widgets ───────────────────────────────── */
@media print {
    body.pols-results .pols-results-focus-areas,
    body.pols-results .pols-results-recap {
        display: none !important;
    }
}

/*─────────────────────────────────────────
 * Phase 4j — Mode badge (session cards)
 *───────────────────────────────────────*/
.pols-mode-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px 3px 6px;
    border-radius: var(--m3-shape-md);
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    cursor: default;
}
.pols-mode-badge__icon {
    display: inline-flex;
    width: 14px;
    height: 14px;
}
.pols-mode-badge__icon svg {
    width: 14px;
    height: 14px;
}
.pols-mode-badge--educatief {
    background: var(--pols-mode-educatief-tint);
    color:      var(--pols-mode-educatief-accent);
}
.pols-mode-badge--interactief {
    background: var(--pols-mode-interactief-tint);
    color:      var(--pols-mode-interactief-accent);
}
.pols-mode-badge--competitief {
    background: var(--pols-mode-competitief-tint);
    color:      var(--pols-mode-competitief-accent);
}

/*─────────────────────────────────────────
 * Phase 4j — Mode picker component
 *───────────────────────────────────────*/
.pols-mode-picker {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin: 0 0 8px;
}
@media (max-width: 720px) {
    .pols-mode-picker {
        grid-template-columns: 1fr;
    }
}
.pols-mode-card {
    appearance: none;
    text-align: left;
    background: #fff;
    border: 2px solid var(--pols-border);
    border-radius: var(--m3-shape-md);
    padding: 14px;
    cursor: pointer;
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard), box-shadow var(--m3-duration-short) var(--m3-easing-standard), transform 0.05s;
    display: flex;
    flex-direction: column;
    gap: 8px;
    color: inherit;
    font-family: inherit;
}
.pols-mode-card:hover:not([disabled]) {
    border-color: var(--pols-primary);
    transform: translateY(-1px);
}
.pols-mode-card:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}
.pols-mode-card.is-selected {
    border-color: var(--card-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--card-accent) 18%, transparent);
}
.pols-mode-card[disabled] {
    cursor: not-allowed;
    opacity: 0.65;
}
.pols-mode-card[data-mode="educatief"]   { --card-accent: var(--pols-mode-educatief-accent); }
.pols-mode-card[data-mode="interactief"] { --card-accent: var(--pols-mode-interactief-accent); }
.pols-mode-card[data-mode="competitief"] { --card-accent: var(--pols-mode-competitief-accent); }
.pols-mode-card__icon {
    width: 32px;
    height: 32px;
    color: var(--card-accent);
}
.pols-mode-card__icon svg {
    width: 32px;
    height: 32px;
}
.pols-mode-card__label {
    font-size: 17px;
    font-weight: 500;
    color: var(--card-accent);
}
.pols-mode-card__tagline {
    font-size: 13px;
    color: var(--pols-text);
    font-weight: 500;
}
.pols-mode-card__meta {
    margin: 6px 0 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 12px;
    line-height: 1.4;
}
.pols-mode-card__meta dt {
    font-weight: 500;
    color: var(--pols-text-muted);
    margin: 0;
}
.pols-mode-card__meta dd {
    margin: 0;
    color: var(--pols-text);
}
.pols-mode-picker__help {
    display: inline-block;
    margin-top: 8px;
    font-size: 13px;
    color: var(--pols-text-muted);
    text-decoration: none;
}
.pols-mode-picker__help:hover {
    color: var(--pols-primary);
    text-decoration: underline;
}

/*─────────────────────────────────────────
 * Phase 4j — New-session modal (slice 4)
 *───────────────────────────────────────*/
.pols-modal--wide {
    max-width: 720px;
    width: 90vw;
}
.pols-modal__body {
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.pols-form-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pols-form-field > label {
    font-size: 13px;
    font-weight: 500;
    color: var(--pols-text-muted);
}
.pols-input.is-invalid {
    border-color: var(--pols-danger);
    box-shadow: inset 0 0 0 1px var(--pols-danger);
}

/*─────────────────────────────────────────
 * Phase 4j — Editor mode section (slice 5)
 *───────────────────────────────────────*/
.pols-editor-mode {
    margin: 0 0 16px;
}
.pols-editor-mode__heading {
    font-size: 13px;
    font-weight: 500;
    color: var(--pols-text-muted);
    margin: 0 0 8px;
    letter-spacing: 0.04em;
}
.pols-editor-mode__notice {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--pols-text-muted);
    font-style: italic;
}

/*─────────────────────────────────────────
 * Phase 4j — Mode-badge popover (slice 6)
 *───────────────────────────────────────*/
.pols-mode-popover {
    position: absolute;
    z-index: 1500;
    width: 320px;
    max-width: calc(100vw - 24px);
    background: #fff;
    border: 1px solid var(--pols-border);
    border-top: 3px solid var(--popover-accent);
    border-radius: var(--m3-shape-sm);
    box-shadow: var(--m3-elev-3);
    padding: 14px 16px;
    font-size: 13px;
    line-height: 1.5;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard), transform var(--m3-duration-short) var(--m3-easing-standard);
    pointer-events: none;
}
.pols-mode-popover.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.pols-mode-popover[data-mode="educatief"]   { --popover-accent: var(--pols-mode-educatief-accent); }
.pols-mode-popover[data-mode="interactief"] { --popover-accent: var(--pols-mode-interactief-accent); }
.pols-mode-popover[data-mode="competitief"] { --popover-accent: var(--pols-mode-competitief-accent); }
.pols-mode-popover__head {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--popover-accent);
    margin-bottom: 6px;
}
.pols-mode-popover__icon svg {
    width: 18px;
    height: 18px;
}
.pols-mode-popover__label {
    font-weight: 500;
    font-size: 14px;
}
.pols-mode-popover__body {
    margin: 0 0 8px;
    color: var(--pols-text);
}
.pols-mode-popover__more {
    display: inline-block;
    font-size: 12px;
    color: var(--pols-text-muted);
    text-decoration: none;
}
.pols-mode-popover__more:hover {
    color: var(--popover-accent);
    text-decoration: underline;
}

/*─────────────────────────────────────────
 * Phase 4j — Help page (modes) — slice 7
 *───────────────────────────────────────*/
.pols-help-modes h1 {
    margin: 0 0 12px;
}
.pols-help-modes__lede {
    font-size: 15px;
    line-height: 1.6;
    margin: 0 0 24px;
    max-width: 760px;
    color: var(--pols-text);
}
.pols-help-modes__cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin: 0 0 32px;
}
@media (max-width: 900px) {
    .pols-help-modes__cards {
        grid-template-columns: 1fr;
    }
}
.pols-help-modes__card {
    background: #fff;
    border: 1px solid var(--pols-border);
    border-top: 4px solid var(--card-accent);
    border-radius: var(--m3-shape-md);
    padding: 18px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.pols-help-modes__card[data-mode="educatief"]   { --card-accent: var(--pols-mode-educatief-accent); }
.pols-help-modes__card[data-mode="interactief"] { --card-accent: var(--pols-mode-interactief-accent); }
.pols-help-modes__card[data-mode="competitief"] { --card-accent: var(--pols-mode-competitief-accent); }
.pols-help-modes__card header {
    display: flex;
    align-items: center;
    gap: 10px;
}
.pols-help-modes__card header h2 {
    margin: 0;
    color: var(--card-accent);
    font-size: 20px;
}
.pols-help-modes__icon {
    color: var(--card-accent);
}
.pols-help-modes__icon svg {
    width: 28px;
    height: 28px;
}
.pols-help-modes__tagline {
    font-weight: 500;
    margin: 0;
}
.pols-help-modes__description {
    margin: 0;
    line-height: 1.5;
}
.pols-help-modes__meta {
    margin: 8px 0 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 13px;
}
.pols-help-modes__meta dt {
    font-weight: 500;
    color: var(--pols-text-muted);
    margin: 0;
}
.pols-help-modes__meta dd {
    margin: 0;
}
.pols-help-modes__table {
    width: 100%;
    border-collapse: collapse;
    margin: 12px 0 8px;
    font-size: 14px;
}
.pols-help-modes__table th,
.pols-help-modes__table td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--pols-border);
}
.pols-help-modes__table thead th {
    background: var(--md-sys-color-surface-container-low);
    font-weight: 500;
}
.pols-help-modes__table td:not(:first-child) {
    text-align: center;
}
.pols-help-modes__table-cell--yes { color: #1a6e2a; font-weight: 500; }
.pols-help-modes__table-cell--no  { color: #9aa0a6; }
.pols-help-modes__footnote {
    font-size: 12px;
    color: var(--pols-text-muted);
    margin: 0 0 24px;
}
.pols-empty-state__hint {
    margin-top: 12px;
    font-size: 13px;
    color: var(--pols-text-muted);
}

/*
 * Phase 4d — Autosave status indicator
 * Inline pill to the left of Cancel / Save buttons via margin-right: auto.
 */
/* Autosave status — quiet M3 supporting text with a 6px state dot.
   saving = outline (pulsing unless reduced motion), saved = tertiary,
   error = danger. */
.pols-editor-form__autosave-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: var(--md-sys-type-body-sm) var(--pols-font);
    letter-spacing: var(--md-sys-type-body-sm-ls);
    color: var(--m3-on-surface-variant);
    margin-right: auto;
    align-self: center;
    transition: opacity var(--m3-duration-medium) var(--m3-easing-standard);
}
.pols-editor-form__autosave-status::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: var(--m3-shape-full);
    background: currentColor;
    flex-shrink: 0;
}
.pols-editor-form__autosave-status:empty::before { content: none; }
.pols-editor-form__autosave-status.is-dirty    { color: var(--m3-on-surface-variant); }
.pols-editor-form__autosave-status.is-saving   { color: var(--m3-outline); }
.pols-editor-form__autosave-status.is-saving::before {
    animation: pols-autosave-pulse 1s var(--m3-easing-standard) infinite;
}
.pols-editor-form__autosave-status.is-saved    { color: var( --pols-success, #2e7d32 ); }
.pols-editor-form__autosave-status.is-error    { color: var( --pols-danger, #d42027 ); }
.pols-editor-form__autosave-status.is-invalid  { color: var( --pols-warning, #b26500 ); }
.pols-editor-form__autosave-status.is-fading   { opacity: 0; }

@keyframes pols-autosave-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
    .pols-editor-form__autosave-status.is-saving::before { animation: none; }
}

/*──────────────────────────────────────────
 * Phase 4e — Institution Settings page
 *────────────────────────────────────────*/

/* Two-column layout: form left, preview right (≥1024px) */
.pols-settings-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 32px;
    align-items: start;
    padding-bottom: 120px; /* room for sticky save footer */
}
@media ( min-width: 1024px ) {
    .pols-settings-layout {
        grid-template-columns: 1fr 340px;
    }
}

/* Section headings */
.pols-settings-section {
    margin-bottom: 40px;
}
.pols-settings-section__title {
    font-size: 16px;
    font-weight: 500;
    color: var(--pols-text);
    margin: 0 0 16px;
    padding-bottom: 8px;
    border-bottom: 1px solid var( --pols-border, #e2e5ea );
}

/* Individual fields */
.pols-settings-field {
    margin-bottom: 20px;
}
.pols-settings-label {
    display: block;
    font-size: 14px;
    font-weight: 500;
    color: var(--pols-text);
    margin-bottom: 6px;
}
.pols-settings-hint {
    font-size: 12px;
    color: var(--pols-muted);
    margin: 4px 0 0;
}
/* Phase 7 slice 2 — plan/usage progress bars (settings page + dashboard indicator) */
.pols-usage-bar {
    height: 8px;
    border-radius: 4px;
    background: var(--m3-surface-container-low);
    border: 1px solid var(--pols-border);
    overflow: hidden;
    margin-top: 6px;
    max-width: 320px;
}
.pols-usage-bar__fill {
    height: 100%;
    background: var(--md-sys-color-primary);
    border-radius: 4px 0 0 4px;
    transition: width 0.3s var(--md-sys-motion-easing-standard);
}
.pols-usage-bar__fill--warn { background: #e88c2a; }
.pols-usage-bar__fill--danger { background: #c0392b; }
.pols-usage-row {
    margin-bottom: 14px;
}
.pols-usage-row:last-child { margin-bottom: 0; }
.pols-usage-row__label {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    color: var(--pols-text);
}
.pols-usage-indicator {
    font-size: 12px;
    color: var(--pols-muted);
    align-self: center;
    margin-right: 12px;
}
.pols-settings-text,
.pols-settings-select,
.pols-settings-number {
    width: 100%;
    max-width: 480px;
}
.pols-settings-number {
    width: 100px;
}
.pols-settings-timer-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.pols-settings-unit {
    font-size: 14px;
    color: var(--pols-muted);
}

/* Color picker row */
.pols-settings-field--color .pols-settings-color-row {
    display: flex;
    align-items: center;
    gap: 10px;
}
.pols-settings-color-input {
    width: 48px;
    height: 36px;
    padding: 2px 4px;
    border: 1px solid var( --pols-border, #e2e5ea );
    border-radius: var(--m3-shape-sm);
    cursor: pointer;
    background: none;
}
.pols-settings-color-hex {
    font-size: 13px;
    font-family: monospace;
    background: var(--pols-bg);
    border: 1px solid var( --pols-border, #e2e5ea );
    border-radius: var(--m3-shape-xs);
    padding: 2px 8px;
}

/* Logo upload area */
.pols-settings-logo-upload {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Alpha.74: a gated branding block is a borderless fieldset, disabled
   (with its upgrade note above it) when the plan has no own branding. */
.pols-settings-fieldset {
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}
.pols-settings-fieldset:disabled {
    opacity: 0.6;
}
/* The upload "buttons" are labels; a disabled input ignores them anyway. */
.pols-settings-fieldset:disabled .pols-settings-upload-btn {
    pointer-events: none;
}
.pols-settings-upgrade {
    margin: 0 0 16px;
    padding: 10px 14px;
    border-radius: 12px;
    background: var(--m3-surface-container);
    color: var(--m3-on-surface);
    font-size: 14px;
}
.pols-settings-favicon-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 12px;
    background: var(--m3-surface-container);
}
.pols-settings-favicon-img {
    width: 32px;
    height: 32px;
    object-fit: contain;
}
.pols-settings-domains {
    margin: 0;
    padding: 0;
    list-style: none;
}
.pols-settings-domains li {
    padding: 4px 0;
}

.pols-settings-logo-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 72px;
    border: 1px dashed var( --pols-border, #e2e5ea );
    border-radius: var(--m3-shape-sm);
    background: var(--pols-bg);
    padding: 12px;
}
.pols-settings-logo-img {
    max-height: 60px;
    max-width: 220px;
    object-fit: contain;
}
.pols-settings-logo-empty {
    font-size: 13px;
    color: var(--pols-muted);
}
.pols-settings-logo-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}
.pols-settings-upload-btn {
    cursor: pointer;
}
.pols-settings-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* Font upload row */
.pols-settings-font-upload {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.pols-settings-font-name {
    font-size: 13px;
    color: var(--pols-text);
    min-width: 80px;
}

/* Ably status label */
.pols-settings-ably-status {
    font-size: 14px;
    color: var(--pols-text);
    margin: 0;
}

/* Toggle / checkbox styled as switch */
.pols-settings-field--toggle {
    margin-top: 12px;
}
.pols-settings-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
}
.pols-settings-toggle__input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.pols-settings-toggle__slider {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    background: var( --pols-border, #e2e5ea );
    border-radius: 11px;
    flex-shrink: 0;
    transition: background var(--m3-duration-medium) var(--m3-easing-standard);
}
.pols-settings-toggle__slider::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    transition: transform var(--m3-duration-medium) var(--m3-easing-standard);
    box-shadow: var(--m3-elev-1);
}
.pols-settings-toggle__input:checked + .pols-settings-toggle__slider {
    background: var( --pols-primary, #1a6e7a );
}
.pols-settings-toggle__input:checked + .pols-settings-toggle__slider::after {
    transform: translateX( 18px );
}
.pols-settings-toggle__label {
    font-size: 14px;
    color: var(--pols-text);
}

/* Sticky save footer */
.pols-settings-save-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 16px;
    padding: 12px 24px;
    background: var( --pols-surface, #fff );
    border-top: 1px solid var( --pols-border, #e2e5ea );
    box-shadow: 0 -2px 8px rgba(0,0,0,.06);
    z-index: 100;
}
.pols-settings-save-footer__hint {
    font-size: 13px;
    color: var(--pols-muted);
}

/* Live preview panel */
.pols-settings-preview {
    position: sticky;
    top: 80px;
}
.pols-settings-preview__title {
    font-size: 14px;
    font-weight: 500;
    color: var(--pols-muted);
    letter-spacing: 0.04em;
    margin: 0 0 12px;
}

/* Preview frames — mini participant screens, one per scheme, side by side
   (alpha.71). Each frame carries its own --md-sys-color-* roles and seed
   colours inline (settings.php renders them, applyPreviewTokens() rewrites
   them from POST /settings/preview-tokens), so these rules read the roles
   directly: the --pols-* aliases resolve on :root and would show the saved
   light scheme in both frames. */
.pols-preview-schemes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.pols-preview-scheme {
    margin: 0;
    min-width: 0;
}
.pols-preview-scheme__label {
    margin-top: 6px;
    font-size: 12px;
    color: var(--pols-muted);
    text-align: center;
}
.pols-preview-schemes__hint {
    margin-top: 10px;
}
.pols-preview-frame {
    border: 1px solid var(--md-sys-color-outline-variant);
    border-radius: var(--m3-shape-md);
    overflow: hidden;
    font-size: 11px;
    background: var(--md-sys-color-surface);
    color: var(--md-sys-color-on-surface);
    box-shadow: var(--m3-elev-1);
    font-family: var(--preview-font, var(--pols-font));
}
.pols-preview-header {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    background: var(--pols-brand-seed);
    color: var(--pols-brand-seed-on);
    min-width: 0;
}
.pols-preview-logo {
    height: 18px;
    max-width: 56px;
    object-fit: contain;
    flex-shrink: 0;
}
/* The header plate, as on the live band (Branding: logo_plate). */
[data-logo-plate="1"] .pols-preview-logo,
.pols-preview-presenter[data-logo-plate="1"] .pols-preview-presenter__logo img {
    background: rgba(255,255,255,0.92); padding: 2px 4px; border-radius: 4px;
}
.pols-preview-logo-placeholder { flex-shrink: 0; }
.pols-preview-inst {
    font-size: 11px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pols-preview-body {
    padding: 10px;
}
.pols-preview-question {
    font-weight: 500;
    margin-bottom: 8px;
    color: var(--md-sys-color-on-surface);
}
.pols-preview-options {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 10px;
}
.pols-preview-option {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 7px;
    background: var(--md-sys-color-surface-container-lowest);
    border: 1px solid var(--md-sys-color-outline-variant);
    border-radius: var(--m3-shape-sm);
    color: var(--md-sys-color-on-surface);
    min-width: 0;
}
/* The selected option shows the secondary container pair, so the admin sees
   the container and its on-colour before saving. */
.pols-preview-option--selected {
    background: var(--md-sys-color-secondary-container);
    border-color: transparent;
    color: var(--md-sys-color-on-secondary-container);
}
.pols-preview-letter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: var(--m3-shape-full);
    background: var(--md-sys-color-primary);
    color: var(--md-sys-color-on-primary);
    font-size: 10px;
    font-weight: 700;
    flex-shrink: 0;
}
.pols-preview-option--selected .pols-preview-letter {
    background: var(--md-sys-color-secondary);
    color: var(--md-sys-color-on-secondary);
}
.pols-preview-btn {
    display: block;
    padding: 6px 10px;
    background: var(--md-sys-color-primary);
    color: var(--md-sys-color-on-primary);
    border-radius: var(--m3-shape-full);
    font-size: 11px;
    font-weight: 500;
    text-align: center;
}
.pols-preview-footer {
    padding: 6px 10px;
    font-size: 10px;
    color: var(--md-sys-color-on-surface-variant);
    border-top: 1px solid var(--md-sys-color-outline-variant);
    text-align: center;
}

/* Preview card — mini presenter (beamer) screen in the selected presenter
   theme, with the same inline roles as the frames above. */
.pols-settings-preview__title--secondary {
    margin-top: 24px;
}
.pols-preview-presenter {
    margin-top: 16px;
    border-radius: var(--m3-shape-lg);
    overflow: hidden;
    background: var(--md-sys-color-surface);
    color: var(--md-sys-color-on-surface);
    box-shadow: var(--m3-elev-2);
    font-size: 12px;
    font-family: var(--preview-font, var(--pols-font));
}
/* The header is the band (alpha.87), set inline per scheme like the
   participant frames'. */
.pols-preview-presenter__header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 12px;
    background: var(--pols-brand-seed);
    color: var(--pols-brand-seed-on);
}
.pols-preview-presenter__brand { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.pols-preview-presenter__logo img {
    height: 18px; max-width: 80px; object-fit: contain; display: block;
}
/* The live interactief chip on the band: a 28% secondary-band tint, its
   text picked against that composite, and the on-colour outline. */
.pols-preview-presenter__chip {
    padding: 2px 8px; border-radius: var(--m3-shape-full);
    background: color-mix(in srgb, var(--pols-brand-secondary-seed) 28%, var(--pols-brand-seed));
    color: var(--pols-header-chip-interactief-on);
    border: 1px solid color-mix(in srgb, var(--pols-brand-seed-on) 45%, transparent);
    font-size: 10px; font-weight: 500; text-transform: uppercase; letter-spacing: .5px;
}
.pols-preview-presenter__question { padding: 14px 12px 8px; font-weight: 500; font-size: 14px; text-align: center; }
.pols-preview-presenter__chart {
    display: flex; align-items: flex-end; justify-content: center; gap: 10px;
    height: 64px; margin: 4px 12px 10px; padding: 8px;
    border-radius: var(--m3-shape-md);
    background: var(--md-sys-color-surface-container-low);
}
/* Chart series: the raw seeds on a light beamer, tone 80 on a dark one
   (Branding::chart_colors()); set inline as --ppr-bar-*. */
.pols-preview-presenter__bar { width: 22px; border-radius: 4px 4px 0 0; }
.pols-preview-presenter__bar--a { height: 70%; background: var(--ppr-bar-a); }
.pols-preview-presenter__bar--b { height: 45%; background: var(--ppr-bar-b); }
.pols-preview-presenter__bar--c { height: 85%; background: var(--ppr-bar-c); }
/* The control bar: the band again, with the main button in the secondary
   band (outlined only when it is too close to the band, data-cta-edge). */
.pols-preview-presenter__controls {
    padding: 8px 12px;
    background: var(--pols-brand-seed);
}
.pols-preview-presenter__cta {
    padding: 6px 0; text-align: center;
    border-radius: var(--m3-shape-full); font-weight: 500;
    background: var(--pols-brand-secondary-seed);
    color: var(--pols-brand-secondary-seed-on);
    border: 1px solid transparent;
}
.pols-preview-presenter[data-cta-edge="1"] .pols-preview-presenter__cta {
    border-color: color-mix(in srgb, var(--pols-brand-seed-on) 45%, transparent);
}
/* Neutral bars (alpha.89): the band variables already hold the surface;
   the bars get the live views' shadow (position: relative, so the slide's
   own background does not paint over it). */
[data-bars="neutral"] .pols-preview-header,
[data-bars="neutral"] .pols-preview-presenter__header,
[data-bars="neutral"] .pols-preview-presenter__controls {
    position: relative;
    box-shadow: var(--pols-band-shadow);
}
[data-bars="neutral"] .pols-preview-presenter__controls {
    box-shadow: var(--pols-band-shadow-up);
}

/* (The --danger role is defined once in the M3 button block near the top of
   this file — outlined-danger with a danger-tinted state layer. The duplicate
   override that lived here pre-M3 was removed in the slice 4 unification.) */

/* ===========================================================
 * Phase 4f — Presenter Management page
 * =========================================================== */

.pols-presenters-invite {
    background: #fff;
    border: 1px solid #e6e8eb;
    border-radius: var(--m3-shape-sm);
    padding: 20px 24px;
    margin-bottom: 24px;
}
.pols-presenters-invite__heading {
    margin: 0 0 16px 0;
    font-size: 16px;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--pols-muted);
}
.pols-presenters-invite__form {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}
@media (min-width: 720px) {
    .pols-presenters-invite__form {
        grid-template-columns: 1fr 1fr;
        gap: 16px 24px;
    }
    .pols-presenters-invite__form .pols-form-field:last-of-type,
    .pols-presenters-invite__submit {
        grid-column: 1 / -1;
    }
}
.pols-presenters-invite__submit {
    display: flex;
    justify-content: flex-end;
}
.pols-presenters-invite__mismatch {
    background: #fff8ec;
    border-left: 3px solid #e8a53a;
    padding: 12px 14px;
    border-radius: var(--m3-shape-sm);
    margin-bottom: 16px;
}
.pols-presenters-invite__mismatch strong {
    display: block;
    margin-bottom: 4px;
    color: #8a5a00;
    font-size: 14px;
}
.pols-presenters-invite__mismatch p {
    margin: 0;
    font-size: 13px;
    color: #5a3a00;
}

/* List */
.pols-presenters-list__heading {
    font-size: 16px;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--pols-muted);
    margin: 0 0 12px 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.pols-presenters-list__count {
    font-size: 13px;
    font-weight: 400;
    color: var(--pols-muted);
    text-transform: none;
    letter-spacing: 0;
}
.pols-presenters-list__loading,
.pols-presenters-list__empty {
    background: #fff;
    border: 1px solid #e6e8eb;
    border-radius: var(--m3-shape-sm);
    padding: 36px 24px;
    text-align: center;
}
.pols-presenters-list__rows {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pols-presenter-row {
    background: #fff;
    border: 1px solid #e6e8eb;
    border-radius: var(--m3-shape-sm);
    padding: 14px 18px;
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    align-items: center;
    transition: box-shadow var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-presenter-row:hover {
    box-shadow: var(--m3-elev-1);
}
@media (min-width: 900px) {
    .pols-presenter-row {
        grid-template-columns: minmax( 0, 2fr ) minmax( 0, 1fr ) auto;
        gap: 16px;
    }
}
.pols-presenter-row__main {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}
.pols-presenter-row__identity {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.pols-presenter-row__name {
    font-weight: 500;
    color: var(--pols-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pols-presenter-row__you {
    font-style: normal;
    font-weight: 400;
    font-size: 12px;
    color: var(--pols-muted);
}
.pols-presenter-row__email {
    font-size: 12px;
    color: var(--pols-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pols-presenter-row__meta {
    font-size: 12px;
    color: var(--pols-muted);
    display: flex;
    gap: 16px;
    align-items: center;
}
.pols-presenter-row__actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.pols-presenter-row__self-note {
    color: var(--pols-muted);
    font-size: 14px;
}

/* Status badges */
.pols-presenter-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--m3-shape-md);
    font-size: 12px;
    font-weight: 500;
    text-transform: lowercase;
    letter-spacing: 0.01em;
    flex-shrink: 0;
}
.pols-presenter-badge.is-active {
    background: color-mix( in srgb, var( --pols-primary ) 10%, #fff );
    color: var( --pols-primary );
}
.pols-presenter-badge.is-suspended {
    background: #fff3ed;
    color: #b26500;
}
.pols-presenter-badge.is-admin {
    background: color-mix( in srgb, var( --pols-tertiary ) 10%, #fff );
    color: var( --pols-tertiary );
}

/* ===========================================================
 * Phase 4k — Session transfer modal
 * =========================================================== */

.pols-modal__subtitle {
    margin: 4px 0 0 0;
    font-size: 13px;
    color: var(--pols-muted);
    font-weight: 400;
}

.pols-transfer-modal__intro {
    margin: 0 0 16px 0;
    color: var(--pols-muted);
    font-size: 13px;
}

.pols-transfer-modal__search {
    margin-bottom: 12px;
}
.pols-transfer-modal__search input {
    width: 100%;
}

.pols-transfer-modal__loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 28px 0;
    color: var(--pols-muted);
    font-size: 13px;
}
.pols-transfer-modal__loading .pols-spinner {
    width: 20px;
    height: 20px;
}

.pols-transfer-modal__empty,
.pols-transfer-modal__error {
    padding: 20px 14px;
    text-align: center;
    margin: 0;
    border-radius: var(--m3-shape-sm);
    font-size: 13px;
}
.pols-transfer-modal__empty {
    background: #f5f7fa;
    color: var(--pols-muted);
}
.pols-transfer-modal__error {
    background: #fff3ed;
    color: #b21515;
}

.pols-transfer-modal__list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 320px;
    overflow-y: auto;
    border: 1px solid #e6e8eb;
    border-radius: var(--m3-shape-sm);
    background: #fff;
}

.pols-transfer-modal__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-bottom: 1px solid #f0f2f5;
    cursor: pointer;
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-transfer-modal__item:last-child {
    border-bottom: none;
}
.pols-transfer-modal__item:hover {
    background: #fafbfd;
}
.pols-transfer-modal__item.is-selected {
    background: color-mix( in srgb, var( --pols-primary ) 8%, #fff );
    box-shadow: inset 3px 0 0 var( --pols-primary );
}

.pols-transfer-modal__identity {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}
.pols-transfer-modal__name {
    font-weight: 500;
    color: var(--pols-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 14px;
}
.pols-transfer-modal__email {
    font-size: 12px;
    color: var(--pols-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pols-transfer-modal__tag {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--m3-shape-md);
    font-size: 11px;
    font-weight: 500;
    flex-shrink: 0;
}
.pols-transfer-modal__tag.is-admin {
    background: color-mix( in srgb, var( --pols-tertiary ) 12%, #fff );
    color: var( --pols-tertiary );
}

/* ==========================================================================
   Phase 5c — Analytics
   ========================================================================== */

.pols-analytics-root {
    padding: 0;
}

.pols-analytics-loading,
.pols-analytics-empty-inline {
    padding: 40px 20px;
    text-align: center;
    color: var(--pols-muted);
}

.pols-analytics-timezone {
    display: inline-block;
    padding: 4px 10px;
    font-size: 12px;
    color: var(--pols-muted);
    background: color-mix( in oklab, var(--pols-muted) 6%, transparent );
    border-radius: var(--m3-shape-md);
}

.pols-analytics-grid {
    display: flex;
    flex-direction: column;
    gap: 32px;
}

/* Headline cards — 4-across on desktop, 2 on tablet, 1 on mobile */
.pols-analytics-cards {
    display: grid;
    grid-template-columns: repeat( 4, 1fr );
    gap: 16px;
}
.pols-analytics-card {
    background: #fff;
    border: 1px solid var(--pols-divider);
    border-radius: var(--m3-shape-md);
    padding: 20px 24px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pols-analytics-card__label {
    font-size: 13px;
    color: var(--pols-muted);
    letter-spacing: 0.04em;
    font-weight: 500;
}
.pols-analytics-card__value {
    font-size: 32px;
    font-weight: 500;
    color: var( --pols-primary, #1a6e7a );
    line-height: 1.2;
}
.pols-analytics-card__sub {
    font-size: 12px;
    color: var(--pols-muted);
}
.pols-analytics-card__sub--hint {
    font-style: italic;
}

/* Section containers for chart + table sections */
.pols-analytics-section {
    background: #fff;
    border: 1px solid var(--pols-divider);
    border-radius: var(--m3-shape-md);
    padding: 24px 28px;
}
.pols-analytics-section h2 {
    margin: 0 0 6px 0;
    font-size: 18px;
    font-weight: 500;
    color: #1a1a1a;
}
.pols-analytics-intro {
    margin: 0 0 20px 0;
    color: var(--pols-muted);
    font-size: 14px;
}

/* Chart containers — fixed height so Chart.js responsive sizing works */
.pols-analytics-chart {
    height: 320px;
    position: relative;
}
.pols-analytics-pie {
    height: 360px;
    position: relative;
    max-width: 720px;
    margin: 0 auto;
}

/* Presenters table */
.pols-analytics-presenters-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.pols-analytics-presenters-table thead th {
    text-align: left;
    padding: 12px 16px;
    font-size: 12px;
    font-weight: 500;
    color: var(--pols-muted);
    letter-spacing: 0.04em;
    border-bottom: 2px solid var(--pols-divider);
}
.pols-analytics-presenters-table tbody td {
    padding: 14px 16px;
    border-bottom: 1px solid var(--pols-divider);
    vertical-align: top;
}
.pols-analytics-presenters-table tbody tr:last-child td {
    border-bottom: 0;
}
.pols-analytics-presenters-table .is-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.pols-analytics-presenters-table__name {
    min-width: 200px;
}
.pols-analytics-presenters-table__email {
    color: var(--pols-muted);
    font-size: 12px;
    margin-top: 2px;
}

/* Empty state on /pols/analytics when has_any_closed_session === false */
.pols-analytics-empty {
    padding: 60px 20px;
    text-align: center;
    background: #fff;
    border: 1px dashed var(--pols-divider);
    border-radius: var(--m3-shape-md);
}
.pols-analytics-empty h2 {
    margin: 0 0 8px 0;
    color: #1a1a1a;
}
.pols-analytics-empty p {
    color: var(--pols-muted);
    margin: 0;
}

/* Error state */
.pols-error-state {
    padding: 32px 20px;
    text-align: center;
    background: #fff4f4;
    border: 1px solid #f4c7c7;
    border-radius: var(--m3-shape-md);
    color: #8b1f1f;
}
.pols-error-state button {
    margin-top: 12px;
}

/* Mobile breakpoint */
@media ( max-width: 900px ) {
    .pols-analytics-cards {
        grid-template-columns: repeat( 2, 1fr );
    }
}
@media ( max-width: 560px ) {
    .pols-analytics-cards {
        grid-template-columns: 1fr;
    }
    .pols-analytics-card__value {
        font-size: 28px;
    }
    .pols-analytics-section {
        padding: 20px 16px;
    }
    .pols-analytics-chart,
    .pols-analytics-pie {
        height: 280px;
    }
    /* Collapse wider columns of the presenters table on mobile:
       hide vote count (least critical), keep sessions + participants. */
    .pols-analytics-presenters-table thead th:nth-child(4),
    .pols-analytics-presenters-table tbody td:nth-child(4) {
        display: none;
    }
}

/* ==========================================================================
   Phase 4h — Network admin
   ========================================================================== */

.pols-network-tabs {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--pols-divider);
    margin-bottom: 24px;
    padding: 0;
}

.pols-network-tabs__tab {
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    padding: 12px 20px;
    font-weight: 500;
    color: var(--pols-muted);
    cursor: pointer;
    transition: color var(--m3-duration-short) var(--m3-easing-standard), border-color var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-network-tabs__tab:hover { color: var( --pols-primary, #1a6e7a ); }
.pols-network-tabs__tab.is-active {
    color: var( --pols-primary, #1a6e7a );
    border-bottom-color: var( --pols-primary, #1a6e7a );
}
.pols-network-tabs__tab:focus-visible {
    outline: 2px solid var( --pols-primary, #1a6e7a );
    outline-offset: 2px;
}

.pols-network-panel[hidden] { display: none; }

.pols-network-loading,
.pols-network-empty,
.pols-network-error {
    padding: 24px;
    color: var(--pols-muted);
    font-size: 14px;
}
.pols-network-error p { margin: 0 0 12px 0; color: #c3292e; }

/* Institutions table */
.pols-network-institutions {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.pols-network-institutions th,
.pols-network-institutions td {
    text-align: left;
    padding: 12px 16px;
    border-bottom: 1px solid var(--pols-divider);
}
.pols-network-institutions th {
    font-weight: 500;
    color: var(--pols-muted);
    font-size: 12px;
    letter-spacing: 0.04em;
}
.pols-network-institutions th.is-numeric,
.pols-network-institutions td.is-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.pols-network-institutions tbody tr:hover {
    background: color-mix( in oklab, var( --pols-primary, #1a6e7a ) 4%, transparent );
}

.pols-network-institutions__name { font-weight: 500; }
.pols-network-tag {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 500;
    background: color-mix( in oklab, var( --pols-primary, #1a6e7a ) 15%, transparent );
    color: var( --pols-primary, #1a6e7a );
    border-radius: var(--m3-shape-md);
}

.pols-network-row-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Settings panel — sticky save footer reuses Phase 4e tokens where
   possible, plus a small nested Ably section. */
.pols-network-settings {
    max-width: 720px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.pols-network-settings__intro {
    color: var(--pols-muted);
    font-size: 14px;
    margin: 0;
}
.pols-network-settings__section {
    border: 1px solid var(--pols-divider);
    border-radius: var(--m3-shape-sm);
    padding: 20px 24px;
    background: #fff;
}
.pols-network-settings__section h3 {
    margin: 0 0 16px 0;
    font-size: 15px;
    font-weight: 500;
}
.pols-network-settings__row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}
.pols-network-settings__row:last-child { margin-bottom: 0; }
.pols-network-settings__row label {
    font-weight: 500;
    font-size: 13px;
}
.pols-network-settings__color {
    display: flex;
    align-items: center;
    gap: 10px;
}
.pols-network-settings__color input[type="color"] {
    width: 44px;
    height: 32px;
    border: 1px solid var(--pols-divider);
    border-radius: var(--m3-shape-xs);
    padding: 0;
    cursor: pointer;
}
.pols-network-settings__color input[type="text"] {
    flex: 0 0 120px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
}
.pols-network-settings__hint {
    color: var(--pols-muted);
    font-size: 12px;
}

.pols-network-ably-current {
    padding: 12px 16px;
    background: color-mix( in oklab, var(--pols-muted) 6%, transparent );
    border-radius: var(--m3-shape-sm);
    font-size: 14px;
    margin-bottom: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.pols-network-ably-current code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
}
.pols-network-ably-clear-hint {
    margin-top: 8px;
    color: #b26a00;
    font-size: 13px;
}
.pols-network-ably-error {
    margin-top: 6px;
    color: #c3292e;
    font-size: 13px;
}

.pols-settings-footer {
    position: sticky;
    bottom: 0;
    background: #fff;
    border-top: 1px solid var(--pols-divider);
    padding: 12px 16px;
    display: flex;
    gap: 12px;
    justify-content: flex-end;
    align-items: center;
    box-shadow: 0 -2px 8px rgba( 0, 0, 0, 0.04 );
    border-radius: 0 0 8px 8px;
}
.pols-settings-footer[hidden] { display: none; }
.pols-settings-footer__status {
    margin-right: auto;
    color: var(--pols-muted);
    font-size: 13px;
}

/* Create form */
.pols-network-create-wrap h2 {
    margin: 0 0 8px 0;
    font-size: 18px;
    font-weight: 500;
}
.pols-network-create__intro {
    color: var(--pols-muted);
    font-size: 14px;
    margin: 0 0 20px 0;
    max-width: 520px;
}
.pols-network-create {
    max-width: 520px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.pols-network-create__field label {
    display: block;
    font-weight: 500;
    margin-bottom: 6px;
    font-size: 13px;
}
.pols-network-create__field input {
    width: 100%;
}
.pols-network-create__hint {
    display: block;
    margin-top: 6px;
    color: var(--pols-muted);
    font-size: 13px;
}
.pols-network-create__hint strong {
    color: var( --pols-primary, #1a6e7a );
    font-weight: 500;
}
.pols-network-create__error {
    margin-top: 6px;
    color: #c3292e;
    font-size: 13px;
}
.pols-network-create__actions {
    display: flex;
    justify-content: flex-start;
}

/* Mobile */
@media ( max-width: 720px ) {
    .pols-network-tabs {
        overflow-x: auto;
        white-space: nowrap;
    }
    .pols-network-institutions th:nth-child(4),
    .pols-network-institutions td:nth-child(4),
    .pols-network-institutions th:nth-child(5),
    .pols-network-institutions td:nth-child(5) {
        display: none; /* hide Participants + Presenters cols on mobile */
    }
    .pols-network-row-actions { flex-direction: column; }
    .pols-network-settings__section {
        padding: 16px;
    }
}

/*──────────────────────────────────────────
 * Phase 6a.2 — Email-first login picker
 *────────────────────────────────────────*/

.pols-login-picker {
    margin-top: 8px;
}

.pols-login-picker__title {
    font-size: 18px;
    font-weight: 500;
    margin: 0 0 8px;
    color: var( --pols-primary );
}

.pols-login-picker__intro {
    font-size: 14px;
    color: var( --pols-text-muted );
    margin: 0 0 16px;
}

.pols-login-picker__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Workspace-picker rows: shape-md list items with M3 state layers. */
.pols-login-picker__link {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-md);
    background: var(--m3-surface-container-lowest);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--m3-duration-short) var(--m3-easing-standard), transform 0.05s;
}
.pols-login-picker__link::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--pols-primary);
    opacity: 0;
    transition: opacity var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-login-picker__link:hover::before         { opacity: 0.08; }
.pols-login-picker__link:focus-visible::before { opacity: 0.10; }
.pols-login-picker__link:active::before        { opacity: 0.12; }

.pols-login-picker__link:hover {
    border-color: var( --pols-primary );
}
.pols-login-picker__link:focus-visible {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}

.pols-login-picker__link:active {
    transform: translateY( 1px );
}

.pols-login-picker__label {
    font-weight: 500;
    font-size: 15px;
}

.pols-login-picker__host {
    font-size: 13px;
    color: var( --pols-text-muted );
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.pols-login-back {
    text-align: center;
    margin: 16px 0 0;
    font-size: 13px;
}

.pols-login-back a {
    color: var( --pols-text-muted );
}

/* ─────────────────────────────────────────────────────────────────
   Phase 6b — Registration, Verification & Domain Routing
   ───────────────────────────────────────────────────────────────── */

/* Welcome banner on dashboard */
.pols-welcome-banner {
    margin-bottom: 20px;
}

/* Check-email page */
.pols-check-email-body {
    margin-bottom: 16px;
}

.pols-check-email-message {
    font-size: 15px;
    margin-bottom: 8px;
}

.pols-check-email-resend {
    border-top: 1px solid var( --pols-border );
    padding-top: 16px;
    margin-top: 16px;
}

.pols-check-email-resend__hint {
    font-size: 13px;
    color: var( --pols-text-muted );
    margin-bottom: 12px;
}

/* Verify-email page */
.pols-verify-state {
    margin: 8px 0 16px;
}

.pols-verify-state .pols-loading {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var( --pols-text-muted );
    font-size: 14px;
}

/* Network domains table */
.pols-network-domains {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 24px;
}

.pols-network-domains th,
.pols-network-domains td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var( --pols-border );
    font-size: 14px;
}

.pols-network-domains th {
    font-weight: 500;
    background: var( --pols-surface );
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var( --pols-text-muted );
}

.pols-network-domains tr:hover td {
    background: color-mix( in srgb, var( --pols-primary ) 4%, transparent );
}

/* Add-domain form */
.pols-network-add-domain {
    max-width: 560px;
}

.pols-network-add-domain-form {
    display: grid;
    gap: 12px;
}

@media ( min-width: 720px ) {
    .pols-network-add-domain-form {
        grid-template-columns: 1fr 1fr auto;
        align-items: end;
    }
    .pols-network-add-domain-form > div:nth-child(3) {
        grid-column: 1 / -2;
    }
}

/* Danger-ghost button variant — same outlined-danger role as --danger but
   with the danger hue on the outline as well (used for destructive row
   actions like institution delete). State layer comes from .pols-btn. */
.pols-btn--danger-ghost {
    background: transparent;
    border-color: var( --pols-danger, #c0392b );
    color: var( --pols-danger, #c0392b );
}

/* Phase 6c — Pending presenter approval UI */

.pols-pending-banner {
    display: flex;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    background: color-mix( in srgb, var( --pols-primary ) 8%, white );
    border: 1px solid color-mix( in srgb, var( --pols-primary ) 20%, white );
    border-radius: var( --pols-radius );
    padding: 0.75rem 1rem;
    margin-bottom: 1.5rem;
}
.pols-pending-banner p { margin: 0; font-weight: 500; }
.pols-pending-banner .pols-btn--link {
    color: var( --pols-primary );
    font-weight: 500;
    white-space: nowrap;
}

.pols-presenters-tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var( --pols-border );
    margin-bottom: 1.5rem;
}
.pols-presenters-tabs__tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0.6rem 1rem;
    cursor: pointer;
    font-weight: 500;
    color: var( --pols-text-muted );
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.pols-presenters-tabs__tab[aria-selected="true"] {
    color: var( --pols-primary );
    border-bottom-color: var( --pols-primary );
}
.pols-presenters-tabs__tab:hover:not( [aria-selected="true"] ) {
    color: var( --pols-text );
}
.pols-presenters-tabs__badge {
    background: var( --pols-primary );
    color: var( --pols-primary-on );
    border-radius: 999px;
    font-size: 0.75rem;
    padding: 0.1rem 0.5rem;
    font-weight: 500;
}

/* Pending rows sit in a subtle surface to visually distinguish from active rows */
.pols-presenters-list__row--pending {
    background: color-mix( in srgb, var( --pols-primary ) 3%, white );
}

/* Global cross-page pending banner (shown in _layout.php on all /pols/* pages) */
.pols-global-pending-banner {
    display: flex;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    background: color-mix( in srgb, var( --pols-secondary ) 10%, white );
    border-left: 4px solid var( --pols-secondary );
    padding: 0.65rem 1rem;
    font-size: 0.95rem;
    margin: 0 0 1.25rem;
}

/* Phase 4i — 403 cross-subsite workspace picker */
.pols-error-page__workspaces {
    list-style: none;
    padding: 0;
    margin: 1rem 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
}
.pols-error-page__logout {
    display: inline-block;
    margin-top: 1.5rem;
    font-size: 0.8125rem;
    color: var( --pols-text-muted );
    text-decoration: underline;
}
.pols-error-page__logout:hover {
    color: var( --pols-text );
}

/* Alpha.66 — 403 claim panel. Reuses the pending shell; the mandatory-mode
   paragraphs are long settled copy, so they read left-aligned like the
   login wizard's claim-mandatory state. */
.pols-claim-panel .pols-claim-panel__text {
    color: var( --pols-text );
    text-align: left;
    line-height: 1.55;
    margin-bottom: 12px;
}

/* Fix B — Pending-presenter self-migration shell */
.pols-pending-shell {
    max-width: 480px;
    margin-inline: auto;
    text-align: center;
    gap: 16px;
}
.pols-pending-shell__desc {
    color: var( --pols-text );
    font-size: 15px;
    line-height: 1.55;
    margin-bottom: 4px;
}
.pols-pending-shell__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin-top: 8px;
}
#pols-switch-status:not(:empty) {
    margin-top: 8px;
    padding: 10px 14px;
    border-radius: var( --pols-radius, 6px );
    font-size: 14px;
    text-align: left;
}

/* Fix C — Profile page */
.pols-profile {
    max-width: 560px;
}
.pols-profile-actions {
    margin-top: 4px;
}

/*──────────────────────────────────────────
 * Ghost button variant (Phase 6d) — legacy alias of the M3 text role.
 * Hover/press tint comes from the .pols-btn state layer (currentColor).
 *────────────────────────────────────────*/
.pols-btn--ghost {
    background: transparent;
    color: var( --pols-primary );
    border-color: transparent;
}

/*──────────────────────────────────────────
 * Phase 6d — First-Run Onboarding
 *────────────────────────────────────────*/

/* Dashboard two-column layout */
.pols-dashboard-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
}

.pols-dashboard-layout--with-checklist {
    grid-template-columns: 1fr 280px;
    gap: 32px;
    align-items: start;
}

@media ( max-width: 900px ) {
    .pols-dashboard-layout--with-checklist {
        grid-template-columns: 1fr;
    }
    .pols-onboarding-checklist {
        order: -1;
    }
}

/* Welcome card */
.pols-onboarding-welcome {
    position: relative;
    background: color-mix( in srgb, var( --pols-primary ) 8%, var( --pols-surface ) );
    border: 1px solid color-mix( in srgb, var( --pols-primary ) 20%, var( --pols-border ) );
    border-radius: var( --pols-radius, 8px );
    padding: 24px 28px;
    margin-bottom: 28px;
}

.pols-onboarding-welcome__dismiss {
    position: absolute;
    top: 12px;
    right: 14px;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 18px;
    color: var(--pols-text-muted);
    line-height: 1;
    padding: 4px 6px;
    border-radius: var(--m3-shape-xs);
    transition: background var(--m3-duration-short) var(--m3-easing-standard);
}
.pols-onboarding-welcome__dismiss:hover {
    background: color-mix( in srgb, var( --pols-primary ) 12%, transparent );
    color: var( --pols-text );
}

.pols-onboarding-welcome__heading {
    font-size: 20px;
    font-weight: 500;
    margin: 0 0 6px;
    color: var( --pols-text );
    padding-right: 32px;
}

.pols-onboarding-welcome__sub {
    color: var(--pols-text-muted);
    font-size: 14px;
    margin: 0 0 18px;
}

.pols-onboarding-welcome__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}

.pols-onboarding-welcome__hint {
    width: 100%;
    margin: 2px 0 0;
    font-size: 13px;
    color: var(--pols-text-muted);
    order: 1;
}

/* Checklist sidebar */
.pols-onboarding-checklist {
    background: var( --pols-surface );
    border: 1px solid var( --pols-border );
    border-radius: var( --pols-radius, 8px );
    overflow: hidden;
    position: sticky;
    top: 80px;
}

.pols-onboarding-checklist__header {
    border-bottom: 1px solid var( --pols-border );
}

.pols-onboarding-checklist__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 14px 16px;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    gap: 8px;
}

.pols-onboarding-checklist__title {
    font-weight: 500;
    font-size: 14px;
    color: var( --pols-text );
    flex: 1;
}

.pols-onboarding-checklist__chevron {
    font-size: 11px;
    color: var(--pols-text-muted);
    transition: transform var(--m3-duration-short) var(--m3-easing-standard);
}

.pols-onboarding-checklist__body {
    padding: 8px 0;
}

.pols-onboarding-checklist__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.pols-onboarding-checklist__item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 16px;
}

.pols-onboarding-checklist__item.is-done {
    opacity: 0.6;
}

.pols-onboarding-checklist__check {
    flex-shrink: 0;
    margin-top: 2px;
    color: var( --pols-primary );
    line-height: 0;
}

.pols-onboarding-checklist__item:not(.is-done) .pols-onboarding-checklist__check {
    color: var( --pols-text-muted, #c0c6cf );
}

.pols-onboarding-checklist__text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.pols-onboarding-checklist__label {
    font-size: 13px;
    font-weight: 500;
    color: var( --pols-text );
    line-height: 1.3;
}

.pols-onboarding-checklist__label--link {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    text-align: left;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--m3-duration-short) var(--m3-easing-standard);
    color: var( --pols-primary );
}
.pols-onboarding-checklist__label--link:hover {
    text-decoration-color: var( --pols-primary );
}

.pols-onboarding-checklist__item.is-done .pols-onboarding-checklist__label {
    color: var(--pols-text-muted);
    text-decoration: none;
    cursor: default;
}

.pols-onboarding-checklist__caption {
    font-size: 11px;
    color: var(--pols-text-muted);
    line-height: 1.3;
}

.pols-onboarding-checklist__success {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 20px 16px;
    text-align: center;
}

.pols-onboarding-checklist__success-icon {
    font-size: 28px;
    line-height: 1;
}

.pols-onboarding-checklist__success p {
    font-size: 13px;
    font-weight: 500;
    margin: 0;
    color: var( --pols-text );
}

/* Demo badge for sample sessions */
.pols-badge--demo {
    background: color-mix( in srgb, var( --pols-primary ) 15%, var( --pols-surface ) );
    color: var( --pols-primary );
    border-color: color-mix( in srgb, var( --pols-primary ) 30%, var( --pols-border ) );
}

.pols-session-card--sample .pols-session-card__title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

/*──────────────────────────────────────────
 * M3 stage 2 — dashboard FAB (mobile only)
 *
 * Hidden by default; JS removes the [hidden] attribute once the click
 * handler is wired, and the media query limits it to phones. Delegates
 * its click to the regular "Nieuwe sessie" button.
 *────────────────────────────────────────*/
.pols-fab {
    display: none;
}
@media (max-width: 720px) {
    .pols-fab:not([hidden]) {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        right: 16px;
        bottom: 16px;
        width: 56px;
        height: 56px;
        border: 0;
        border-radius: var(--m3-shape-lg);
        background: var(--pols-primary-container);
        color: var(--pols-on-primary-container);
        box-shadow: var(--m3-elev-3);
        cursor: pointer;
        z-index: 90;
        transition: transform var(--m3-duration-short) var(--m3-easing-emphasized),
                    box-shadow var(--m3-duration-short) var(--m3-easing-standard);
    }
    .pols-fab:not([hidden]):active {
        transform: scale(0.96);
    }
    .pols-fab:not([hidden]):focus-visible {
        outline: 2px solid var(--pols-primary);
        outline-offset: 2px;
    }
}

/*──────────────────────────────────────────
 * M3 stage 2 — skeleton loaders (dashboard session grid)
 * Shimmer disabled under prefers-reduced-motion.
 *────────────────────────────────────────*/
.pols-skeleton-card {
    background: var(--m3-surface-container-lowest);
    border-radius: var(--m3-shape-xl);
    box-shadow: var(--m3-elev-1);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 140px;
}
.pols-skeleton {
    border-radius: var(--m3-shape-xs);
    background: linear-gradient(
        90deg,
        var(--m3-surface-container) 25%,
        var(--m3-surface-container-high) 37%,
        var(--m3-surface-container) 63%
    );
    background-size: 400% 100%;
    animation: pols-skeleton-shimmer 1.4s var(--m3-easing-standard) infinite;
}
.pols-skeleton--title { height: 20px; width: 60%; }
.pols-skeleton--line  { height: 13px; width: 100%; }
.pols-skeleton--short { width: 40%; }

@keyframes pols-skeleton-shimmer {
    0%   { background-position: 100% 0; }
    100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
    .pols-skeleton { animation: none; }
}

/*──────────────────────────────────────────
 * Phase 6a.3 — Auth then picker
 *────────────────────────────────────────*/

.pols-login-state[hidden] { display: none; }

.pols-login-register-prompt {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pols-login-register-prompt__body {
    margin: 0;
    font-size: 14px;
    color: var( --pols-text );
    text-align: center;
}

/* Kind badge inside picker links — sits between label and host, right-aligned with host. */
.pols-login-picker__link {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 12px;
    row-gap: 2px;
    align-items: baseline;
}

.pols-login-picker__label { grid-column: 1; grid-row: 1; }
.pols-login-picker__kind  { grid-column: 1; grid-row: 2; font-size: 12px; color: var( --pols-text-muted ); }
.pols-login-picker__host  { grid-column: 2; grid-row: 1 / span 2; align-self: center; }

.pols-login-picker__link[data-kind="personal"] .pols-login-picker__kind {
    color: var( --pols-primary );
}

.pols-login-picker__empty {
    padding: 14px 16px;
    border: 1px dashed var( --pols-border );
    border-radius: var( --pols-radius );
    background: var( --pols-surface );
    color: var( --pols-text-muted );
    font-size: 14px;
    text-align: center;
}

/*──────────────────────────────────────────
 * Phase 6h — confirm / sent / elsewhere / claim login states
 *────────────────────────────────────────*/

.pols-login-confirm,
.pols-login-sent,
.pols-login-elsewhere,
.pols-login-claim {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pols-login-confirm__lead,
.pols-login-elsewhere__lead,
.pols-login-elsewhere__body,
.pols-login-sent__body,
.pols-login-claim__body {
    margin: 0;
    font-size: 14px;
    color: var( --pols-text );
    text-align: center;
}

/* The echoed address. Deliberately the loudest thing on the screen — the
   whole point of the confirm step is that the user re-reads what they typed.
   break-all so a long address never overflows the auth card. */
.pols-login-confirm__address {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid var( --pols-border );
    border-radius: var( --pols-radius );
    background: var( --pols-surface );
    font-size: 17px;
    font-weight: 500;
    text-align: center;
    word-break: break-all;
    color: var( --pols-text );
}

.pols-login-confirm__suggestion {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
/* An author-origin `display` beats the UA stylesheet's `[hidden]{display:none}`
   regardless of specificity, so any element we set `display` on AND toggle via
   the `hidden` property needs its own guard or it is permanently visible. The
   state containers get this from `.pols-login-state[hidden]` above; this block
   is toggled independently by renderConfirm(), so it needs its own. */
.pols-login-confirm__suggestion[hidden] { display: none; }
.pols-login-confirm__suggestion p {
    margin: 0;
    font-size: 14px;
    text-align: center;
    color: var( --pols-text );
}
.pols-login-confirm__suggestion strong { word-break: break-all; }

.pols-login-sent__heading,
.pols-login-claim__heading {
    margin: 0;
    font-size: 18px;
    font-weight: 500;
    text-align: center;
    color: var( --pols-text );
}

.pols-login-sent__body strong { word-break: break-all; }

.pols-login-sent__hint,
.pols-login-claim__reassurance,
.pols-login-claim__at-cap {
    margin: 0;
    font-size: 13px;
    color: var( --pols-text-muted );
    text-align: center;
}

/* Inline link-looking button used by the "← Ander e-mailadres" backlink. */
.pols-linkbutton {
    background: none;
    border: 0;
    padding: 0;
    color: var( --pols-primary );
    font: inherit;
    cursor: pointer;
    text-decoration: underline;
}
.pols-linkbutton:hover,
.pols-linkbutton:focus-visible {
    color: var( --md-sys-color-primary );
}

/*──────────────────────────────────────────
 * Phase 6i — Workspace conversion
 *────────────────────────────────────────*/

/* Read-only banner. Same layout as the three existing global banners; only
   the tint differs, because this one announces a deadline rather than a
   queue someone can work through at their leisure. */
.pols-global-pending-banner--readonly {
    background: color-mix( in srgb, var( --pols-tertiary, #b8860b ) 12%, white );
    border-left-color: var( --pols-tertiary, #b8860b );
}

/* Header status block on /pols/workspace-transfer. */
.pols-wt-status {
    padding: 14px 16px;
    margin: 0 0 20px;
    border: 1px solid var( --pols-border );
    border-left: 4px solid var( --pols-border );
    border-radius: var( --pols-radius );
    background: var( --pols-surface );
}
.pols-wt-status--mandatory {
    border-left-color: var( --pols-tertiary, #b8860b );
    background: color-mix( in srgb, var( --pols-tertiary, #b8860b ) 6%, white );
}
.pols-wt-status__intro {
    margin: 0;
    font-size: 15px;
    color: var( --pols-text );
}
.pols-wt-status__meta {
    margin: 6px 0 0;
    font-size: 14px;
    font-weight: 500;
    color: var( --pols-text );
}

/* Download-responsibility card + the "not allowed" paragraph. */
.pols-wt-download {
    margin-bottom: 20px;
}
.pols-wt-download h2 {
    margin: 0 0 6px;
    font-size: 17px;
}
.pols-wt-download p {
    margin: 0;
    font-size: 14px;
    color: var( --pols-text-muted );
}
.pols-wt-export-note {
    margin-top: 10px !important;
    padding: 10px 12px;
    border-radius: var( --pols-radius-sm );
    background: #fff4e5;
    border: 1px solid #fddaa5;
    color: #7a3e00 !important;
}

.pols-wt-list {
    margin-bottom: 24px;
}
.pols-wt-count {
    margin-left: 6px;
    font-weight: 400;
    color: var( --pols-text-muted );
}
/* .pols-btn is display:inline-flex, which beats the UA's [hidden] rule — the
   bulk actions toggle their `hidden` attribute, so they need this. Scoped to
   this page rather than made global to keep it away from .pols-fab and every
   other button that already reasons about [hidden] itself. */
.pols-wt-list .pols-btn[hidden] {
    display: none;
}

/* Sequential bulk-copy progress. */
.pols-wt-progress {
    margin: 0 0 14px;
}
.pols-wt-progress .pols-usage-bar {
    max-width: none;
}
.pols-wt-progress__label {
    margin: 6px 0 0;
    font-size: 13px;
    color: var( --pols-text-muted );
}

.pols-wt-truncated {
    margin-bottom: 16px;
}

/* The session table reuses the .pols-network-institutions rules (including
   .is-numeric); only the wrapper and the cell-specific bits are new. The
   wrapper scrolls so the page body never does. */
.pols-wt-table-wrap {
    overflow-x: auto;
    border: 1px solid var( --pols-border );
    border-radius: var( --pols-radius );
    background: var( --pols-surface );
}
.pols-wt-table {
    min-width: 720px;
}
.pols-wt-table__select {
    width: 40px;
}
.pols-wt-table__name {
    display: block;
    font-weight: 500;
}
.pols-wt-table__date {
    display: block;
    font-size: 12px;
    color: var( --pols-text-muted );
}
.pols-wt-table__actions {
    white-space: nowrap;
}
.pols-wt-table__actions .pols-btn {
    margin: 2px 4px 2px 0;
}
.pols-wt-state-error {
    background: #fbeaea;
    color: #8a1e1e;
}
.pols-wt-state-message {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    color: var( --pols-text-muted );
    max-width: 260px;
    white-space: normal;
}

/* Results boundary block. */
.pols-wt-results h2 {
    margin: 0 0 6px;
    font-size: 17px;
}
.pols-wt-results > p {
    margin: 0;
    font-size: 14px;
    color: var( --pols-text-muted );
}
.pols-wt-results__subheading {
    margin: 16px 0 8px;
    font-size: 14px;
    font-weight: 500;
}
.pols-wt-results__downloads {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Mandatory-mode claim: four paragraphs, so left-aligned and spaced —
   the centred single-line treatment of the optional prompt does not carry
   an argument this long. */
.pols-claim-mandatory .pols-modal__body p {
    margin: 0 0 12px;
    font-size: 14px;
    line-height: 1.55;
    color: var( --pols-text );
}
.pols-claim-mandatory .pols-modal__body p:last-child {
    margin-bottom: 0;
}
.pols-login-claim--mandatory .pols-login-claim__body,
.pols-login-claim--mandatory .pols-login-claim__reassurance {
    text-align: left;
    line-height: 1.55;
}

@media (max-width: 720px) {
    .pols-wt-table__actions .pols-btn {
        display: block;
        width: 100%;
        margin: 0 0 6px;
    }
    /* The triage table borrows .pols-network-institutions for its chrome, and
       that class hides columns 4 and 5 below 720px — written for Network
       Admin's Participants/Presenters columns. Here those same positions are
       Antwoorden and Status: the response count the user needs in order to
       decide what to export, and the only place the page reports what has
       already been copied or left. Re-shown here rather than by narrowing the
       Network Admin rule, which is correct for its own table. Equal
       specificity, later in the file — no !important needed. Nothing is
       gained by hiding them: .pols-wt-table is min-width:720px inside an
       overflow-x:auto wrapper, so the table already scrolls on a phone. */
    .pols-wt-table th:nth-child(4),
    .pols-wt-table td:nth-child(4),
    .pols-wt-table th:nth-child(5),
    .pols-wt-table td:nth-child(5) {
        display: table-cell;
    }
}

/*──────────────────────────────────────────
 * Accessibility — reduced motion (mirror of the guard in pols.css)
 *────────────────────────────────────────*/
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/*──────────────────────────────────────────
 * Gewone slides in the editor (alpha.79)
 *────────────────────────────────────────*/

/* Picker step 1 (two kinds), layout thumbnails, the back button. */
.pols-editor-type-picker__grid--kinds {
    grid-template-columns: repeat(2, 1fr);
}
/* Six layout presets (alpha.80): three by two. */
.pols-editor-type-picker__grid--presets {
    grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 720px) {
    .pols-editor-type-picker__grid--presets {
        grid-template-columns: repeat(2, 1fr);
    }
}
.pols-editor-type-picker__tile--kind {
    min-height: 220px;
    justify-content: center;
    padding: 28px 24px;
}
.pols-editor-type-picker__tile--kind .pols-editor-type-picker__tile-label {
    font-size: 18px;
}
.pols-editor-type-picker__tile .pols-layout-icon {
    width: 96px;
    height: 54px;
}
.pols-editor-type-picker__back + .pols-editor-type-picker__title {
    flex: 1 1 auto;
}

/* Content form: fields left, live preview right. */
.pols-editor-form--content {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 440px);
    gap: 24px;
    align-items: start;
}
.pols-editor-form--content .pols-editor-form__fields {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}
.pols-editor-form--content .pols-editor-form__footer {
    grid-column: 1 / -1;
}
/* The image group (field, hints, alt text, fit, side) stacks like the
   fields around it. Two classes, so the [hidden] rule below still wins. */
.pols-editor-form--content .pols-editor-form__group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* [hidden] must win over the display of field classes. */
.pols-editor-form--content [data-content-for][hidden],
.pols-editor-form--content [data-content-hidden-image][hidden] {
    display: none;
}
.pols-editor-form__choices {
    display: flex;
    flex-direction: row; /* over .pols-editor-form__field's column */
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    padding: 0;
    border: 0;
}
.pols-editor-form__choices legend {
    width: 100%;
    margin-bottom: 6px;
    font: var(--md-sys-type-label-lg) var(--pols-font);
    color: var(--m3-on-surface);
}
.pols-editor-form__choice {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-full);
    cursor: pointer;
    font: var(--md-sys-type-label-lg) var(--pols-font);
}
.pols-editor-form__choice:has(input:checked) {
    background: var(--pols-secondary-container);
    color: var(--pols-on-secondary-container);
    border-color: transparent;
}
.pols-editor-form__choice:has(input:focus-visible) {
    outline: 2px solid var(--pols-primary);
    outline-offset: 2px;
}
.pols-editor-form__toolbar {
    display: flex;
    gap: 8px;
    margin-bottom: 6px;
}
/* Paragraph classes carry the form's class: .pols-app p (0,1,1) sets a 12px margin. */
.pols-editor-form--content .pols-editor-form__hint {
    margin: 6px 0 0;
    font: var(--md-sys-type-body-md) var(--pols-font);
    color: var(--m3-on-surface-variant);
}
.pols-editor-form--content .pols-editor-form__hint.is-error {
    color: var(--md-sys-color-error);
}
.pols-editor-form--content .pols-editor-form__notice {
    margin: 0;
    padding: 10px 14px;
    border-radius: var(--m3-shape-md);
    background: var(--m3-surface-container);
    font: var(--md-sys-type-body-md) var(--pols-font);
}
/* Not sticky: .pols-editor-slide has overflow: hidden, which would make the card the scroll container. */
.pols-editor-form--content .pols-content-preview__label {
    margin: 0 0 8px;
    font: var(--md-sys-type-label-lg) var(--pols-font);
    color: var(--m3-on-surface-variant);
}
.pols-content-preview__stage {
    overflow: hidden;
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-md);
    background: var(--m3-surface);
}
.pols-editor-form--content .pols-content-preview__warning {
    margin: 8px 0 0;
    font: var(--md-sys-type-body-md) var(--pols-font);
    color: var(--md-sys-color-error);
}

@media (max-width: 1024px) {
    .pols-editor-form--content {
        grid-template-columns: minmax(0, 1fr);
    }
    .pols-content-preview {
        order: -1;
    }
}
@media (max-width: 480px) {
    .pols-editor-type-picker__grid--kinds,
    .pols-editor-type-picker__grid--presets {
        grid-template-columns: 1fr;
    }
}

/*──────────────────────────────────────────
 * Alpha.86 — institution signups review (/pols/network → Aanmeldingen)
 *────────────────────────────────────────*/

/* Count badges: the tab, and the Netwerk link in the app nav. */
.pols-network-tabs__badge,
.pols-app-nav__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    margin-left: 6px;
    border-radius: var(--m3-shape-full);
    background: var(--pols-tertiary);
    color: var(--pols-tertiary-on);
    font: var(--md-sys-type-label-sm) var(--pols-font);
    font-weight: 700;
    line-height: 1;
    vertical-align: middle;
}
.pols-network-tabs__badge[hidden],
.pols-app-nav__badge[hidden] { display: none; }

.pols-signups-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}
.pols-signups-toolbar .pols-select { width: auto; min-width: 180px; }
.pols-signups-list {
    display: grid;
    gap: 16px;
    margin-top: 16px;
}

.pols-signup {
    background: var(--m3-surface-container-lowest);
    border: 1px solid var(--m3-outline-variant);
    border-radius: var(--m3-shape-lg);
    padding: 20px 24px;
    scroll-margin-top: 96px;
}
.pols-signup.is-pending { border-left: 4px solid var(--pols-secondary); }
.pols-signup.is-focus { box-shadow: 0 0 0 3px var(--pols-primary-container); }
.pols-signup.is-busy { opacity: 0.6; }

.pols-signup__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}
/* Two classes: .pols-app h3 / p (0,1,1) would otherwise set margins and type. */
.pols-signup .pols-signup__name {
    margin: 0;
    font: var(--md-sys-type-title-lg) var(--pols-font);
    color: var(--m3-on-surface);
}
.pols-signup .pols-signup__host {
    margin: 2px 0 0;
    font: var(--md-sys-type-body-md) var(--pols-font);
    color: var(--m3-on-surface-variant);
}
.pols-signup .pols-signup__host a { color: var(--pols-primary); }
.pols-signup .pols-signup__meta {
    margin: 8px 0 0;
    font: var(--md-sys-type-body-sm) var(--pols-font);
    color: var(--m3-on-surface-variant);
}

.pols-signup__status {
    flex: none;
    padding: 4px 10px;
    border-radius: var(--m3-shape-full);
    font: var(--md-sys-type-label-md) var(--pols-font);
}
.pols-signup__status--pending_review { background: var(--pols-secondary-container); color: var(--pols-on-secondary-container); }
.pols-signup__status--active         { background: var(--pols-success-container);   color: var(--pols-on-success-container); }
.pols-signup__status--declined       { background: var(--m3-surface-container-high); color: var(--m3-on-surface-variant); }

.pols-signup__facts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px 24px;
    margin: 16px 0 0;
}
.pols-signup__facts .is-wide { grid-column: 1 / -1; }
.pols-signup__facts dt {
    font: var(--md-sys-type-label-md) var(--pols-font);
    color: var(--m3-on-surface-variant);
}
.pols-signup__facts dd {
    margin: 2px 0 0;
    font: var(--md-sys-type-body-md) var(--pols-font);
    color: var(--m3-on-surface);
    white-space: pre-line;
    overflow-wrap: anywhere;
}
.pols-signup__facts dd a { color: var(--pols-primary); }
.pols-signup__domain {
    display: inline-block;
    margin: 0 6px 6px 0;
    padding: 2px 8px;
    border-radius: var(--m3-shape-sm);
    background: var(--pols-primary-container);
    color: var(--pols-on-primary-container);
    font: var(--md-sys-type-label-md) var(--pols-font);
}

.pols-signup .pols-alert { margin: 16px 0 0; }
.pols-signup .pols-alert p { margin: 0 0 6px; }
.pols-signup__carve {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    cursor: pointer;
}
.pols-signup__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 20px;
}

.pols-modal .pols-signup-decline__label {
    display: block;
    margin: 12px 0 6px;
    font: var(--md-sys-type-label-lg) var(--pols-font);
}
.pols-modal .pols-textarea { width: 100%; }

@media (max-width: 600px) {
    .pols-signup { padding: 16px; }
    .pols-signup__head { flex-direction: column; }
    .pols-signup__actions .pols-btn { flex: 1 1 auto; }
}
