/* ========== WallPhotoEditor ========== */

.editor-toolbar { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; background: var(--topbar-bg); border-radius: 10px 10px 0 0; gap: 8px; flex-wrap: wrap; min-height: 44px; box-sizing: border-box; }
.editor-bottom { display: flex; flex-direction: column; border-radius: 0 0 10px 10px; overflow: hidden; }
.editor-bottom > :last-child { border-radius: 0 0 10px 10px; }
.editor-bottom:empty { display: none; }
.toolbar-left { display: flex; align-items: center; gap: 8px; }
.toolbar-right { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.toolbar-sep { width: 1px; height: 20px; background: rgba(255,255,255,0.2); margin: 0 2px; }
.hold-count { color: rgba(255,255,255,0.7); font-size: 0.8rem; }
.tool-btn { background: rgba(255,255,255,0.1); border: none; color: white; padding: 6px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.tool-btn:hover { background: rgba(255,255,255,0.2); }
.tool-btn.active { background: var(--accent); }
.tool-btn.active.danger { background: #cc2244; }
.tool-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.option-bar { display: flex; align-items: center; gap: 10px; padding: 6px 12px; background: #22223a; flex-wrap: wrap; }
.option-group { display: flex; align-items: center; gap: 4px; }
.option-group.swatches { flex-wrap: wrap; max-width: 100%; }
.option-group label { color: rgba(255,255,255,0.6); font-size: 0.75rem; }
.option-group input[type=range] { width: 60px; accent-color: var(--accent); }
.option-hint { color: rgba(255,255,255,0.4); font-size: 0.7rem; font-style: italic; }
.opt-btn { padding: 3px 10px; border: 1px solid rgba(255,255,255,0.3); background: none; color: white; border-radius: 4px; font-size: 0.75rem; cursor: pointer; }
.opt-btn.active { background: #2196F3; border-color: #2196F3; }

/* Hold usage tool */
.usage-list { display: flex; flex-wrap: wrap; gap: 6px; }
.usage-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border: 1px solid rgba(255,255,255,0.25); border-radius: 999px; background: rgba(255,255,255,0.06); color: #fff; font-size: 0.75rem; text-decoration: none; }
.usage-chip:hover { background: rgba(255,255,255,0.14); }
.usage-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.usage-dot.start { background: #4CAF50; }
.usage-dot.normal { background: #2196F3; }
.usage-dot.top { background: #9C27B0; }
.usage-grade { color: rgba(255,255,255,0.6); font-size: 0.7rem; }
.usage-flag { color: rgba(255,255,255,0.55); font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.04em; border: 1px solid rgba(255,255,255,0.25); border-radius: 4px; padding: 0 4px; }
.opt-btn.foot.active { background: #8D6E63; border-color: #8D6E63; }
.opt-btn.danger { border-color: var(--accent); color: var(--accent); }
.opt-btn.danger:hover { background: var(--accent); color: white; }
.color-select { padding: 2px 4px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.3); background: #1a1a2e; color: white; font-size: 0.75rem; }
.color-dot { width: 14px; height: 14px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.3); display: inline-block; }
.color-swatch { width: 22px; height: 22px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.3); cursor: pointer; padding: 0; }
.color-swatch.active { border-color: white; box-shadow: 0 0 0 2px rgba(255,255,255,0.5); }
.cb-label { display: flex; align-items: center; gap: 4px; color: white; font-size: 0.75rem; cursor: pointer; }
.cb-label input { accent-color: #8D6E63; }
.name-input { padding: 3px 8px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.3); background: #1a1a2e; color: white; font-size: 0.75rem; width: 120px; }

.batch-bar { display: flex; gap: 6px; padding: 8px 12px; background: var(--secondary); }
.batch-save { flex: 1; padding: 8px; background: #4CAF50; color: white; border: none; border-radius: 6px; font-weight: 600; font-size: 0.85rem; cursor: pointer; }
.batch-save:hover { background: #43A047; }
.batch-discard { padding: 8px 16px; background: none; color: rgba(255,255,255,0.8); border: 1px solid rgba(255,255,255,0.3); border-radius: 6px; font-size: 0.85rem; cursor: pointer; }
.batch-discard:hover { background: rgba(255,255,255,0.1); }

.zoom-bar { display: flex; gap: 4px; padding: 4px 12px; background: #22223a; align-items: center; }
.zoom-btn { padding: 4px 12px; background: rgba(255,255,255,0.1); border: none; color: white; border-radius: 4px; cursor: pointer; font-size: 0.85rem; }
.zoom-btn:hover { background: rgba(255,255,255,0.2); }
.zoom-label { color: rgba(255,255,255,0.5); font-size: 0.75rem; margin-left: 4px; }
.zoom-sep { width: 1px; height: 16px; background: rgba(255,255,255,0.2); margin: 0 4px; }
.zoom-btn.pan-active { background: var(--accent); }
.zoom-btn svg { display: block; }

/* Every viewport driven by wwwroot/js/viewport.js must opt out of native gestures,
   otherwise browser scrolling/zooming competes with our handlers. */
/* Default to pan-y so a not-zoomed viewport lets the finger scroll the PAGE; viewport.js
   flips this to `none` (inline) the moment the content is zoomed in and it owns the gesture. */
.photo-viewport,
.picker-viewport,
.schematic-viewport { touch-action: pan-y; overscroll-behavior: contain; }
.photo-viewport { height: 70vh; overflow: auto; -webkit-overflow-scrolling: touch; }
/* Boulder detail: the box is sized to the image's aspect ratio (set inline by
   bwViewport.fitBox once the photo loads), so a short photo leaves no dead band AND the
   box height stays put while zooming — the zoomed content scrolls inside it rather than
   growing the card. `height: auto` lets the aspect-ratio drive the height; it is only the
   fallback (before load / on error) that would otherwise track the content. */
.photo-viewport.photo-section { height: auto; max-height: 80vh; }

/* Framed view: the photo + overlay are cropped to the wall region (--crop-scale + a bbox-aspect
   box, both set by bwViewport.fitBox). The widened content overflows the box in both axes at fit,
   so hide the scrollbars for a clean crop — panning still works via the scroll model once zoomed. */
.photo-viewport.bw-framed { scrollbar-width: none; }
.photo-viewport.bw-framed::-webkit-scrollbar { width: 0; height: 0; }


/* "First-fold" layout: the wall editor + stats panels size to fit in the visible
   viewport (accounting for sticky bw-topbar and fixed bw-tabbar), with a peek so
   the Boulders header + first row remain visible to signal scrollable content. */
:root {
    --topbar-h: 56px;       /* sticky .bw-topbar */
    --bottomnav-h: 72px;    /* fixed .bw-tabbar + safe-area */
    --fold-peek: 140px;     /* reserve below the fold for boulder peek */
    /* Vertical space taken by the chrome ABOVE/around each photo box, subtracted from the window
       so the fullscreen/desktop layout can size the photo to fit without scrolling. Deliberately
       generous (slightly under-estimates available height) so the image is guaranteed contained. */
    --boulder-photo-chrome: 96px;   /* back link + title + grade + wall-dim bar + margins */
    --wall-photo-chrome: 168px;     /* carousel padding + toggle row + dim bar + dots + gaps */
}
.wall-fold {
    height: calc(100dvh - var(--topbar-h) - var(--bottomnav-h) - var(--fold-peek));
    min-height: 360px;      /* don't collapse to nothing on short windows */
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.wall-fold .wall-detail-card { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
    border-radius: 12px; background: var(--bg-surface); }
.wall-fold .wall-detail-card > .detail-header,
.wall-fold .wall-detail-card > .bw-anon-notice,
.wall-fold .wall-detail-card > .description,
.wall-fold .wall-detail-card > .view-toggle { padding-left: 12px; padding-right: 12px; }
.wall-fold .wall-detail-card > .detail-header { padding-top: 10px; }
.wall-fold .wall-detail-card > .view-toggle { margin-bottom: 0; padding-bottom: 8px; }
.wall-fold .wall-photo-container { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.wall-fold .photo-viewport,
.wall-fold .schematic-viewport { flex: 1 1 0; height: auto; min-height: 0; }
.wall-fold .editor-toolbar { border-radius: 0; }
.wall-fold .editor-bottom > :last-child { border-radius: 0; }
/* --zoom is written by JS (viewport.js) and by nothing else. Razor only ever renders
   the element without a width so a late server re-render cannot stomp the transform. */
/* No touch-action here: the parent .photo-viewport owns it (viewport.js). A `none` on
   this content child would override the viewport's pan-y and re-block page scrolling. */
/* --crop-scale (default 1) is written by JS (viewport.js fitBox) when the view is framed to the
   wall region: it widens the shared content layer so the region fills the box, composing with
   --zoom in the same calc. Both custom properties are JS-owned; Razor renders no width. */
.photo-editor { position: relative; overflow: hidden; user-select: none;
    -webkit-touch-callout: none; -webkit-user-select: none;
    width: calc(var(--zoom, 1) * var(--crop-scale, 1) * 100%); min-width: 100%; }
/* Corner rounding lives on the CONTAINER, not on .photo-editor. The wall single-image path rounds
   via its .photo-viewport (pages.css). The multi-panel/boulder path uses the transform model
   (viewport.js translate+scale on .photo-editor): a transformed child escapes the parent
   .photo-section's rounded overflow clip on iOS Safari, so it still needs the radius on the layer
   itself — scoped here to those panels only, so the wall editor no longer carries the band-aid. */
.photo-section .photo-editor { border-radius: 12px; }
/* Forbid the native image drag (desktop click-drag ghost) and the iOS tap-and-hold
   callout / selection, so a press-drag pans (see viewport-gestures.js) instead of
   grabbing the image. Mirrors the .stitcher-layer precedent in pages.css. */
.photo-editor .wall-photo { width: 100%; display: block;
    -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }
.photo-editor .hold-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* Editor Move mode only: the draggable hold shapes take touch-action:none so a one-finger
   press-drag moves the hold (pointer events) instead of the browser scrolling. Scoped by the
   [data-hold-drag] marker so it never touches the .photo-editor content child at large (which
   would re-block the viewport's JS-owned pan-y/none toggle — see the note near .photo-editor). */
.photo-editor[data-hold-drag] .hold-overlay circle,
.photo-editor[data-hold-drag] .hold-overlay polygon,
.photo-editor[data-hold-drag] .hold-overlay rect { touch-action: none; }
/* Boulder viewer only: the overlay holds are display-only (no tap/click handlers), so let
   pointer/touch events fall through to the viewport. Otherwise a mouse drag or double-tap that
   happens to start on a hold is treated as landing on an interactive shape and neither pans nor
   zooms (viewport-gestures.js isInteractiveTarget). Editors, which DO drag holds, are unaffected. */
.boulder-detail .hold-overlay { pointer-events: none; }
.detecting-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--overlay-bg); display: flex; align-items: center; justify-content: center; color: white; font-size: 1.1rem; font-weight: 600; }

/* ========== WallSchematicView ========== */

.schematic-container {
    background: var(--bg-surface); border-radius: 12px;
    box-shadow: 0 2px 8px var(--shadow-md); overflow: hidden;
}
.zoom-controls { display: flex; gap: 4px; padding: 8px 12px; background: var(--topbar-bg); }
.schematic-viewport { height: 70vh; overflow: auto; -webkit-overflow-scrolling: touch; }
.schematic-svg { display: block; }
.schematic-viewport > .schematic-svg { width: calc(var(--zoom, 1) * 100%); min-width: 100%; }
.schematic-info { text-align: center; padding: 8px; font-size: 0.8rem; color: var(--text-secondary); }

/* ========== Hold + wall colours ==========
   The foot (orange) and top (purple) tokens every hold-related surface uses. Kept in sync
   with BoulderHoldColors.Foot / BoulderHoldColors.Top (Components/Shared/BoulderHoldColors.cs),
   which is what the SVG overlays paint with. --wall-bg / --wall-floor drive the schematic
   wall rectangle and floor line. */
:root {
    --foot-hold: #FF9800;
    --foot-hold-soft: rgba(255, 152, 0, 0.18);
    --foot-hold-text: #E65100;
    --top-hold: #9C27B0;
    --top-hold-soft: rgba(156, 39, 176, 0.18);
    --top-hold-text: #7B1FA2;
    --wall-bg: #f5f0eb;
    --wall-floor: #8D6E63;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --foot-hold: #FFB74D;
        --foot-hold-soft: rgba(255, 183, 77, 0.18);
        --foot-hold-text: #FFCC80;
        --top-hold: #CE93D8;
        --top-hold-soft: rgba(206, 147, 216, 0.18);
        --top-hold-text: #E1BEE7;
        --wall-bg: #1c1c28;
        --wall-floor: #6b5a52;
    }
}

[data-theme="dark"] {
    --foot-hold: #FFB74D;
    --foot-hold-soft: rgba(255, 183, 77, 0.18);
    --foot-hold-text: #FFCC80;
    --top-hold: #CE93D8;
    --top-hold-soft: rgba(206, 147, 216, 0.18);
    --top-hold-text: #E1BEE7;
    --wall-bg: #1c1c28;
    --wall-floor: #6b5a52;
}

/* ========== BoulderRulesEditor ========== */

.rules-block { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.rules-title { font-size: 0.85rem; font-weight: 700; color: var(--text-heading); }
.rule-group {
    display: flex; flex-direction: column; gap: 6px;
    padding: 10px; border: 1px solid var(--border); border-radius: var(--r-md);
    background: var(--bg-surface-alt);
}
.rule-group-label { font-size: 0.78rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
.rules-block .radio-label { align-items: flex-start; }
/* The shared .radio-label / .checkbox-label checked state hardcodes a light pink; use
   the themed token here so the block stays readable in dark mode. */
.rules-block .radio-label:has(input:checked),
.rules-block .checkbox-label:has(input:checked) { background: var(--accent-soft); }
.radio-text { display: flex; flex-direction: column; gap: 2px; }
.radio-text small { font-weight: 400; font-size: 0.75rem; color: var(--text-secondary); }
.rule-sub { display: flex; flex-direction: column; gap: 6px; margin-left: 14px; padding-left: 10px; border-left: 2px solid var(--border); }
.foot-color-swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.color-swatch.foot-swatch { border-color: var(--border); }
.color-swatch.foot-swatch.active { border-color: var(--foot-hold); box-shadow: 0 0 0 2px var(--foot-hold-soft); }
.color-swatch.foot-swatch.absent { opacity: 0.35; }
.rule-hint { font-size: 0.75rem; color: var(--text-secondary); }
.rule-hint .rule-warn { color: var(--warning-text); display: block; }
.rule-notice {
    font-size: 0.78rem; padding: 8px 10px; border-radius: var(--r-sm);
    background: var(--warning-bg); color: var(--warning-text);
}

/* ========== HoldPicker ========== */

.picker-toolbar { padding: 8px 12px; background: var(--topbar-bg); border-radius: 10px 10px 0 0; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 6px; }
.pick-count { color: rgba(255,255,255,0.7); font-size: 0.85rem; }
.pick-legend { display: flex; gap: 10px; }
.legend-item { color: rgba(255,255,255,0.6); font-size: 0.75rem; display: flex; align-items: center; gap: 4px; }
.pick-legend .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.pick-legend .dot.start { background: #4CAF50; }
.pick-legend .dot.normal { background: #2196F3; }
.pick-legend .dot.top { background: #9C27B0; }
/* The picker toolbar sits on a dark bar in both themes, so a fixed orange is used
   here rather than the theme-aware --foot-hold. */
.pick-legend .dot.foot { background: #FF9800; }
.pick-controls { display: flex; gap: 4px; align-items: center; }
.pick-controls .separator { width: 1px; height: 20px; background: rgba(255,255,255,0.2); margin: 0 2px; }
.mode-btn { padding: 4px 10px; border: 1px solid rgba(255,255,255,0.3); background: none; color: white; border-radius: 4px; font-size: 0.8rem; cursor: pointer; display: flex; align-items: center; gap: 4px; }
.mode-btn.active { background: #2196F3; border-color: #2196F3; }
.mode-btn.start-active { background: #4CAF50; border-color: #4CAF50; }
.mode-btn.top-active { background: #9C27B0; border-color: #9C27B0; }
.mode-btn.view-active { background: rgba(255,255,255,0.2); border-color: rgba(255,255,255,0.5); }

.usage-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 6px; padding: 8px 12px; background: var(--topbar-bg); border-radius: 0 0 10px 10px; }
.usage-hint { color: rgba(255,255,255,0.55); font-size: 0.75rem; }
.usage-controls { display: flex; gap: 4px; align-items: center; }
.usage-btn { padding: 5px 10px; border: 1px solid rgba(255,255,255,0.3); background: none; color: white; border-radius: 4px; font-size: 0.75rem; cursor: pointer; display: flex; align-items: center; gap: 5px; }
.usage-btn.active { background: var(--accent); border-color: var(--accent); }
.usage-btn.foot.active { background: #FF9800; border-color: #FF9800; }
@media (max-width: 480px) { .usage-btn span { display: none; } .usage-btn { padding: 6px 10px; } }

.picker-viewport { max-height: 70vh; overflow: auto; -webkit-overflow-scrolling: touch; border-radius: 0; }
.photo-picker { position: relative; overflow: hidden; user-select: none;
    width: calc(var(--zoom, 1) * 100%); min-width: 100%; }
.photo-picker .wall-photo { width: 100%; display: block; }
.photo-picker .hold-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.schematic-picker { overflow: hidden; background: var(--wall-bg); user-select: none;
    width: calc(var(--zoom, 1) * 100%); min-width: 100%; }
.schematic-picker .schematic-svg { width: 100%; display: block; }

/* ========== Background (wall photo) visibility ==========
   --wall-dim (0..1) and .bw-wall-focus are set on <html> by wwwroot/js/wall-dim.js
   from localStorage, so the setting costs no server round-trips, survives every
   Blazor re-render, and applies to every surface at once. Only the <img> is filtered
   — the hold SVG overlay is a sibling and stays at full contrast. */
img.wall-photo {
    filter: brightness(calc(1 - (var(--wall-dim, 0) * 0.8)))
            saturate(calc(1 - (var(--wall-dim, 0) * 0.7)));
    transition: filter 120ms linear;
}
.bw-wall-focus img.wall-photo { filter: brightness(0.3) saturate(0.12) contrast(1.15); }

/* Focus mode also thickens hold outlines on the read-only/picking surfaces. The
   editor is left alone so its drag handles keep their calibrated hit sizes. */
.bw-wall-focus .photo-section .hold-overlay :is(circle, rect, polygon),
.bw-wall-focus .photo-picker .hold-overlay :is(circle, rect, polygon) {
    stroke-width: 0.75;
    paint-order: stroke fill;
}

.wall-dim-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 2px 12px; min-height: 34px; box-sizing: border-box;
    background: var(--bg-surface-alt); color: var(--text-secondary);
    border-bottom: 1px solid var(--border);
}
.wall-dim-bar > svg { flex: 0 0 auto; opacity: 0.7; }
.wall-dim-bar input[type="range"] { flex: 1 1 auto; min-width: 0; height: 28px; accent-color: var(--accent); }
.wall-dim-focus {
    flex: 0 0 auto; padding: 6px 14px; min-height: 30px;
    border: 1px solid var(--border); background: var(--bg-surface); color: var(--text);
    border-radius: var(--r-pill); font-size: 0.75rem; font-weight: 600; cursor: pointer;
}
:root.bw-wall-focus .wall-dim-focus { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Inside the dark editor/picker chrome the bar adopts the surrounding toolbar look. */
.zoom-bar + .wall-dim-bar,
.photo-viewport + .wall-dim-bar {
    background: #22223a; color: rgba(255,255,255,0.6); border-bottom: none;
}
.zoom-bar + .wall-dim-bar .wall-dim-focus,
.photo-viewport + .wall-dim-bar .wall-dim-focus {
    background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.25); color: #fff;
}

/* ========== GradePicker ========== */

.grade-picker { display: flex; align-items: center; gap: 6px; }
.scale-toggle { display: flex; gap: 2px; }
.scale-btn {
    padding: 4px 8px; border: 1px solid var(--border); background: var(--bg-surface);
    border-radius: 4px; font-size: 0.75rem; cursor: pointer; color: var(--text-secondary);
}
.scale-btn.active { background: var(--topbar-bg); color: white; border-color: var(--topbar-bg); }
.grade-select {
    padding: 8px 10px; border: 2px solid var(--border); border-radius: 8px;
    font-size: 1rem; font-weight: 700; background: var(--input-bg); min-width: 80px;
    color: var(--text);
}

/* ========== Wall segments ==========
   Segment editor + roster. Colours are design tokens so the panel matches both themes;
   the SVG overlays stay fixed hues from WallSegmentPalette. */
.segment-editor { display: flex; flex-direction: column; gap: 10px; }
.segment-editor-bar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.segment-editor .segment-viewport { height: 46vh; min-height: 240px; border-radius: var(--r-md); overflow: auto; }
.segment-hint { font-size: 0.78rem; color: var(--text-secondary); margin: 0; }
.segment-empty { font-size: 0.82rem; color: var(--text-secondary); margin: 0; }

.segment-list { display: flex; flex-direction: column; gap: 8px; }
.segment-row {
    display: flex; flex-direction: column; gap: 8px; padding: 10px;
    border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--r-md);
    background: var(--bg-surface-alt); cursor: pointer;
}
.segment-row.active { border-color: var(--accent); background: var(--accent-soft); }
.segment-row-head { display: flex; align-items: center; gap: 8px; }
.segment-badge {
    flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; color: #fff;
    font-size: 0.75rem; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.segment-name {
    flex: 1 1 auto; min-width: 0; padding: 5px 8px; font-size: 0.9rem; font-weight: 600;
    border: 1px solid var(--border); border-radius: var(--r-sm);
    background: var(--input-bg); color: var(--text);
}
.segment-order { display: flex; gap: 4px; flex: 0 0 auto; }
.segment-row-body { display: flex; flex-direction: column; gap: 6px; }

/* Segment type (Wall / Floor). Shares the facing-toggle look; a Floor is trimmed from the schematic. */
.segment-kind { display: flex; gap: 4px; }
.kind-btn {
    flex: 1 1 0; padding: 5px 8px; font-size: 0.78rem; font-weight: 600;
    border: 1px solid var(--border); border-radius: var(--r-sm);
    background: var(--input-bg); color: var(--text-secondary); cursor: pointer;
}
.kind-btn:hover { border-color: var(--accent); color: var(--text); }
.kind-btn.active { border-color: var(--accent); background: var(--accent-soft); color: var(--text-heading); }

/* Collapsible wall-segment settings: clutter-free by default, open to adjust the projection. */
.segment-settings > summary {
    cursor: pointer; font-weight: 600; color: var(--text-heading);
    padding: 8px 0; list-style: revert; display: flex; align-items: center; gap: 8px;
}
.segment-settings-count {
    font-size: 0.72rem; font-weight: 600; color: var(--text-secondary);
    background: var(--accent-soft); border-radius: 999px; padding: 1px 8px;
}
.segment-angle-label { font-size: 0.8rem; font-weight: 600; color: var(--text-heading); }
.segment-angle-word { font-weight: 400; color: var(--text-secondary); }
.segment-warn { font-size: 0.72rem; color: var(--warning-text); }
.segment-vertices { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; color: var(--text-secondary); }

/* Facing (yaw) control: a plain-language 3-way toggle over WallSegment.Yaw, with the raw
   degrees tucked behind "Fine-tune". Tokenised so it matches both themes. */
.segment-facing { display: flex; flex-direction: column; gap: 6px; }
.segment-facing-label { font-size: 0.8rem; font-weight: 600; color: var(--text-heading); }
.facing-toggle { display: flex; gap: 4px; flex-wrap: wrap; }
.facing-btn {
    flex: 1 1 0; min-width: 84px; padding: 5px 8px; font-size: 0.78rem; font-weight: 600;
    border: 1px solid var(--border); border-radius: var(--r-sm);
    background: var(--input-bg); color: var(--text-secondary); cursor: pointer;
}
.facing-btn:hover { border-color: var(--accent); color: var(--text); }
.facing-btn.active { border-color: var(--accent); background: var(--accent-soft); color: var(--text-heading); }
.facing-advanced-toggle {
    align-self: flex-start; padding: 0; font-size: 0.74rem; font-weight: 600;
    background: none; border: none; color: var(--accent); cursor: pointer; text-decoration: underline;
}
.facing-fine { display: flex; flex-direction: column; gap: 4px; }
.facing-fine-label { font-size: 0.76rem; color: var(--text-secondary); }

/* Live folded preview inside the segment editor: the shared schematic, size-capped so it
   sits under the drawing surface without dominating the settings panel. */
.segment-preview { display: flex; flex-direction: column; gap: 4px; }
.segment-preview-label { font-size: 0.76rem; font-weight: 600; color: var(--text-secondary); }
.segment-preview .schematic-viewport { height: 34vh; min-height: 200px; }

/* ============================================================================
   New boulder-setting experience: experience toggle, radial classify overlay.
   All colours come from the theme tokens so both light and dark read correctly.
   ============================================================================ */

.experience-banner {
    display: flex; flex-direction: column; gap: 2px; width: 100%;
    text-align: left; padding: 12px 16px; margin-bottom: 14px;
    border: 1px solid var(--border); border-left: 4px solid var(--top-hold);
    border-radius: 12px; cursor: pointer; background: var(--bg-surface-alt);
    color: var(--text); transition: border-color 0.12s ease, background 0.12s ease;
}
.experience-banner:hover { border-color: var(--top-hold); background: var(--bg-surface); }
.experience-banner:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.experience-banner-title { font-weight: 600; color: var(--text-heading); }
.experience-banner-sub { font-size: 0.8rem; color: var(--text-secondary); }

.experience-footer { margin-top: 18px; text-align: center; }
.btn-link {
    background: none; border: none; color: var(--text-secondary);
    text-decoration: underline; cursor: pointer; font-size: 0.85rem; padding: 8px;
}
.btn-link:hover { color: var(--text); }
.btn-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.new-rules { margin-top: 12px; }

/* The "+ Virtual" tool row below the image (radial mode). Unlike the dark picker toolbar,
   this sits on the page surface, so the button uses theme tokens, not white-on-dark. */
.radial-controls { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.radial-controls .pick-count { color: var(--text-secondary); font-size: 0.85rem; }
.radial-controls .mode-btn { color: var(--text); border-color: var(--border); min-height: 40px; }
.radial-controls .mode-btn.active { color: #fff; }

/* Radial classify overlay. Rendered as fixed-position HTML (never inside the zoomed SVG),
   so it keeps a constant on-screen size regardless of pinch zoom. */
.classify-backdrop { position: fixed; inset: 0; z-index: 1000; background: transparent; }

/* The overlay is sized around a responsive dial. When the hold is already in the boulder the root
   grows to make room for the outer bin ring; otherwise it is exactly the dial. */
.classify-root {
    /* --x/--y are the tapped hold's viewport coordinates, fed in from the picker. Clamp the centre
       by a half-diameter so the full dial always stays on-screen — a hold near the top edge would
       otherwise push the Top/finish wedge off the top of the viewport and out of reach. */
    --half: calc(clamp(180px, 46vw, 260px) / 2);
    position: fixed; z-index: 1001; transform: translate(-50%, -50%);
    display: grid; place-items: center; touch-action: manipulation;
    width: clamp(180px, 46vw, 260px); height: clamp(180px, 46vw, 260px);
    left: clamp(var(--half), var(--x, 50vw), calc(100vw - var(--half)));
    top: clamp(var(--half), var(--y, 50vh), calc(100vh - var(--half)));
}
.classify-root.has-ring {
    /* The bin ring adds 76px to the diameter, so the safe half-diameter grows by 38px. */
    --half: calc(clamp(180px, 46vw, 260px) / 2 + 38px);
    width: calc(clamp(180px, 46vw, 260px) + 76px);
    height: calc(clamp(180px, 46vw, 260px) + 76px);
}
.classify-ring {
    position: absolute; inset: 0; grid-area: 1 / 1; border-radius: 50%;
    border: 2px solid var(--border); background: var(--bg-surface-alt);
    box-shadow: 0 10px 34px var(--shadow-lg);
}
.classify-dial {
    position: relative; grid-area: 1 / 1;
    width: clamp(180px, 46vw, 260px); height: clamp(180px, 46vw, 260px);
    border-radius: 50%; overflow: hidden;
    border: 2px solid var(--border); background: var(--bg-surface);
    box-shadow: 0 10px 34px var(--shadow-lg);
}
.classify-bin {
    position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%); z-index: 3;
    width: 52px; height: 52px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--border); background: var(--bg-surface); color: var(--danger-text);
    cursor: pointer; box-shadow: 0 2px 12px var(--shadow-md);
}
.classify-bin:hover { border-color: var(--danger-text); }
.classify-bin:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.classify-wedge {
    position: absolute; inset: 0; padding: 0; border: none; cursor: pointer;
    /* Solid fallback first so browsers without color-mix() still render distinguishable wedges. */
    background: var(--bg-surface-alt);
    background: color-mix(in srgb, var(--wedge-color) 22%, var(--bg-surface));
    transition: background 0.12s ease;
}
.classify-wedge:hover,
.classify-wedge:focus-visible {
    background: var(--bg-surface-alt);
    background: color-mix(in srgb, var(--wedge-color) 42%, var(--bg-surface));
}
.classify-wedge:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.classify-wedge.current {
    background: var(--bg-surface-alt);
    background: color-mix(in srgb, var(--wedge-color) 58%, var(--bg-surface));
}
.classify-label {
    position: absolute; display: flex; flex-direction: column; align-items: center; gap: 4px;
    pointer-events: none; font-size: 0.72rem; font-weight: 600;
}
.classify-dot { width: 14px; height: 14px; border-radius: 50%; box-shadow: 0 0 0 2px var(--bg-surface); }
.classify-text { color: var(--text-heading); }
.classify-close {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 64px; height: 64px; border-radius: 50%; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--border); background: var(--bg-surface); color: var(--text);
    cursor: pointer; box-shadow: 0 2px 12px var(--shadow-md);
}
.classify-close:hover { color: var(--text-heading); border-color: var(--text-secondary); }
.classify-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
