/* ==========================================================================
   Droneworxs portal — design system
   --------------------------------------------------------------------------
   Loaded after css/app.css on every page. app.css still supplies UIkit's
   layout primitives (uk-grid, uk-width-*, uk-flex) and the Material Design
   Icons webfont; everything below replaces the visual skin on top of it.

   Every rule is scoped under html.v2 so it outweighs the class-level rules
   in app.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
html.v2 {
    --dw-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --dw-mono: 'SFMono-Regular', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

    --dw-r-sm: 8px;
    --dw-r: 12px;
    --dw-r-lg: 16px;
    --dw-r-xl: 20px;

    --dw-bg: #f1f3f7;
    --dw-surface: #ffffff;
    --dw-surface-2: #f6f7fa;
    --dw-surface-3: #eceff4;
    --dw-border: #e4e8ef;
    --dw-border-strong: #d2d8e3;
    --dw-text: #0d1117;
    --dw-text-2: #475264;
    --dw-muted: #78849a;

    --dw-accent: #f0a01e;
    --dw-accent-2: #da7d02;
    --dw-accent-soft: rgba(240, 160, 30, .12);
    --dw-on-accent: #231806;

    --dw-info: #2f6feb;
    --dw-info-soft: rgba(47, 111, 235, .1);
    --dw-good: #16a35c;
    --dw-good-soft: rgba(22, 163, 92, .1);
    --dw-warn: #cf8a00;
    --dw-warn-soft: rgba(207, 138, 0, .12);
    --dw-bad: #d64545;
    --dw-bad-soft: rgba(214, 69, 69, .1);
    /* Sleep is a fourth camera state, not a degree of fault: a muted blue-grey
       that sits beside good/warn/bad without competing with any of them. */
    --dw-sleep: #7b8aa6;
    --dw-sleep-soft: rgba(123, 138, 166, .14);

    /* The colours above are tuned as fills — dots, bars, segments. At 11–13px
       on the light surfaces they land at 2.4–3.3:1, under AA, so text and icon
       roles use these darker variants instead. */
    --dw-good-text: #0f7a44;
    --dw-warn-text: #8a5a00;
    --dw-bad-text: #b53535;
    --dw-info-text: #2354b8;
    --dw-accent-text: #8a4f00;
    --dw-sleep-text: #5b6a85;

    --dw-rail: #101319;
    --dw-rail-text: #f3f5f9;
    --dw-rail-muted: #98a2b3;
    --dw-rail-hover: rgba(255, 255, 255, .08);
    --dw-rail-line: rgba(255, 255, 255, .08);

    --dw-shadow-1: 0 1px 2px rgba(13, 17, 23, .04), 0 1px 3px rgba(13, 17, 23, .06);
    --dw-shadow-2: 0 22px 44px -22px rgba(13, 17, 23, .34), 0 4px 14px -8px rgba(13, 17, 23, .18);
    --dw-shadow-3: 0 32px 64px -28px rgba(13, 17, 23, .45), 0 8px 20px -12px rgba(13, 17, 23, .25);

    --dw-scrim: rgba(241, 243, 247, .9);

    --dw-topbar-h: 64px;
    --dw-rail-w: 260px;
    --dw-rail-w-mini: 72px;
}

html.v2[data-dw-theme="dark"] {
    --dw-bg: #0b0d11;
    --dw-surface: #14181f;
    --dw-surface-2: #1a1f28;
    --dw-surface-3: #212733;
    --dw-border: #242a34;
    --dw-border-strong: #333a47;
    --dw-text: #eef1f6;
    --dw-text-2: #b4bdcb;
    --dw-muted: #8794a8;

    --dw-accent-soft: rgba(240, 160, 30, .16);

    --dw-info: #6b9bff;
    --dw-info-soft: rgba(107, 155, 255, .14);
    --dw-good: #2ecc82;
    --dw-good-soft: rgba(46, 204, 130, .14);
    --dw-warn: #f0b429;
    --dw-warn-soft: rgba(240, 180, 41, .14);
    --dw-bad: #f47272;
    --dw-bad-soft: rgba(244, 114, 114, .14);
    --dw-sleep: #8fa2c2;
    --dw-sleep-soft: rgba(143, 162, 194, .16);

    /* Dark already clears AA at 7–9:1, so the text roles reuse the fills. */
    --dw-good-text: #2ecc82;
    --dw-warn-text: #f0b429;
    --dw-bad-text: #f47272;
    --dw-info-text: #6b9bff;
    --dw-accent-text: #f0a01e;
    --dw-sleep-text: #9fb1cf;

    --dw-rail: #0e1116;

    --dw-shadow-1: 0 1px 2px rgba(0, 0, 0, .5);
    --dw-shadow-2: 0 26px 52px -24px rgba(0, 0, 0, .85), 0 6px 16px -8px rgba(0, 0, 0, .6);
    --dw-shadow-3: 0 36px 72px -28px rgba(0, 0, 0, .9), 0 10px 24px -12px rgba(0, 0, 0, .7);

    --dw-scrim: rgba(11, 13, 17, .93);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
html.v2 {
    -webkit-text-size-adjust: 100%;
    background: var(--dw-bg);
}

html.v2 body {
    margin: 0;
    min-height: 100vh;
    position: relative;
    font-family: var(--dw-font);
    font-size: 14px;
    line-height: 1.5;
    color: var(--dw-text);
    background-color: var(--dw-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

html.v2 body.dw-has-banner {
    background-repeat: repeat-y;
    background-size: 100% auto;
    background-position: top center;
}

html.v2 body.dw-has-banner::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: var(--dw-scrim);
    pointer-events: none;
    z-index: 0;
}

html.v2 h1, html.v2 h2, html.v2 h3,
html.v2 h4, html.v2 h5, html.v2 h6 {
    font-family: var(--dw-font);
    color: var(--dw-text);
    font-weight: 600;
    letter-spacing: -.015em;
    margin: 0 0 12px;
}

html.v2 h1 { font-size: 28px; }
html.v2 h2 { font-size: 22px; }
html.v2 h3 { font-size: 18px; }
html.v2 h4 { font-size: 16px; }
html.v2 h5 { font-size: 14px; }
html.v2 h6 { font-size: 13px; }

html.v2 a { color: var(--dw-accent-2); text-decoration: none; }
html.v2 a:hover { color: var(--dw-accent); text-decoration: none; }
html.v2 p { margin: 0 0 12px; }
html.v2 hr { border-top: 1px solid var(--dw-border); }
html.v2 code, html.v2 pre, html.v2 kbd {
    font-family: var(--dw-mono);
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-sm);
    color: var(--dw-text-2);
}
html.v2 code { padding: 1px 5px; font-size: 12.5px; }
html.v2 pre { padding: 14px 16px; font-size: 12.5px; overflow-x: auto; }

html.v2 ::selection { background: var(--dw-accent); color: var(--dw-on-accent); }

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

html.v2 .dw-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The UA sheet's `[hidden] { display: none }` loses to any rule that sets an
   explicit display, and most components here do. Everything that toggles
   visibility — the filter grid, the flash messages, the range panel, the empty
   states — sets el.hidden, so this has to win. */
html.v2 [hidden] { display: none !important; }

html.v2 .dw-ico { width: 18px; height: 18px; flex: none; }

/* Thin, unobtrusive scrollbars everywhere. */
html.v2 * { scrollbar-width: thin; scrollbar-color: var(--dw-border-strong) transparent; }
html.v2 ::-webkit-scrollbar { width: 10px; height: 10px; }
html.v2 ::-webkit-scrollbar-track { background: transparent; }
html.v2 ::-webkit-scrollbar-thumb {
    background: var(--dw-border-strong);
    border: 3px solid transparent;
    border-radius: 99px;
    background-clip: content-box;
}
html.v2 ::-webkit-scrollbar-thumb:hover { background-color: var(--dw-muted); background-clip: content-box; }

/* --------------------------------------------------------------------------
   3. App shell
   -------------------------------------------------------------------------- */
html.v2 .dw-shell { display: flex; flex-direction: column; min-height: 100vh; position: relative; z-index: 1; }

/* --- top bar --- */
html.v2 .dw-topbar {
    position: sticky;
    top: 0;
    z-index: 60;
    background: var(--dw-rail);
    /* An inset line rather than a border: a real border-bottom makes the bar
       --dw-topbar-h + 1px tall, while the rail below is sized and stuck at
       exactly --dw-topbar-h — so every page ended up 1px taller than the
       viewport and scrolled past its own bottom edge. */
    box-shadow: inset 0 -1px 0 var(--dw-rail-line);
    color: var(--dw-rail-text);
}
html.v2 .dw-topbar-inner {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: var(--dw-topbar-h);
    padding: 0 clamp(12px, 2vw, 24px);
}
html.v2 .dw-brand { display: flex; align-items: center; flex: none; }
html.v2 .dw-brand img { height: 26px; width: auto; display: block; }

html.v2 .dw-topbar-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--dw-rail-text);
    padding-left: 4px;
    border-left: 1px solid var(--dw-rail-line);
    margin-left: 4px;
    padding: 4px 0 4px 16px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
html.v2 .dw-topbar-spacer { flex: 1; min-width: 0; }

html.v2 .dw-iconbtn {
    width: 38px; height: 38px;
    border-radius: 11px;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent;
    border: 1px solid transparent;
    color: var(--dw-rail-text);
    cursor: pointer;
    transition: background .16s, border-color .16s, color .16s;
    flex: none;
    padding: 0;
}
html.v2 .dw-iconbtn:hover { background: var(--dw-rail-hover); border-color: rgba(255, 255, 255, .1); color: #fff; }
html.v2 .dw-iconbtn .dw-ico { width: 19px; height: 19px; }
html.v2 .dw-iconbtn .mdi { font-size: 20px; line-height: 1; }

html.v2[data-dw-theme="dark"] .dw-theme-sun { display: none; }
html.v2:not([data-dw-theme="dark"]) .dw-theme-moon { display: none; }

/* The download / API key / live image components render UIkit navbar
   dropdowns, so they keep their navbar wrapper — restyled to sit in the
   dark top bar rather than look like a second navigation. */
html.v2 .dw-navbar-actions {
    background: transparent;
    border: 0;
    min-height: 0;
    padding: 0;
    flex: none;
}
html.v2 .dw-navbar-actions .uk-navbar-nav { gap: 4px; }
html.v2 .dw-navbar-actions .uk-navbar-nav > li > a {
    width: 38px; height: 38px; min-height: 0;
    padding: 0; margin: 0;
    border-radius: 11px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--dw-rail-text);
    background: transparent;
    border: 1px solid transparent;
    font-size: 0;
    transition: background .16s, border-color .16s;
}
html.v2 .dw-navbar-actions .uk-navbar-nav > li > a:hover,
html.v2 .dw-navbar-actions .uk-navbar-nav > li.uk-open > a {
    background: var(--dw-rail-hover);
    border-color: rgba(255, 255, 255, .1);
    color: #fff;
}
html.v2 .dw-navbar-actions .uk-navbar-nav > li > a .mdi { font-size: 20px; line-height: 1; }
html.v2 .dw-navbar-actions .uk-navbar-nav > li > a::after { display: none; }
html.v2 .dw-navbar-actions .uk-navbar-dropdown { margin-top: 6px; }

/* --- account menu --- */
html.v2 .dw-user { position: relative; flex: none; }
html.v2 .dw-user-btn {
    /* Border-box, so `height` is the pill's real height and the padding is the
       inset around the logo rather than added on top of it. A pill needs more
       room left and right than top and bottom before it reads as even, and the
       caret needs its own breathing space before the rounded end. */
    box-sizing: border-box;
    display: flex; align-items: center; gap: 8px;
    height: 44px; padding: 0 13px 0 11px;
    border-radius: 999px; cursor: pointer;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .1);
    color: var(--dw-rail-text);
    transition: background .16s;
}
html.v2 .dw-user-btn:hover { background: rgba(255, 255, 255, .1); }
html.v2 .dw-user-btn img { height: 30px; max-width: 92px; object-fit: contain; border-radius: 7px; background: transparent; }
html.v2 .dw-user-btn .dw-avatar-fallback {
    width: 30px; height: 30px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--dw-accent); color: var(--dw-on-accent);
    font-weight: 700; font-size: 12.5px;
}
html.v2 .dw-user-btn .dw-ico {
    /* The icon font draws at the inherited 1.5 line-height, so a bare glyph
       sits below the middle of its 15px box; centring it in a flex box puts
       the caret on the same line as the logo. */
    display: flex; align-items: center; justify-content: center; line-height: 1;
    width: 15px; height: 15px; flex: none;
    color: var(--dw-rail-muted); transition: transform .18s;
}
html.v2 .dw-user-btn[aria-expanded="true"] .dw-ico { transform: rotate(180deg); }

html.v2 .dw-menu {
    position: absolute; right: 0; top: calc(100% + 10px);
    min-width: 224px; padding: 6px;
    background: var(--dw-surface); color: var(--dw-text);
    border: 1px solid var(--dw-border);
    border-radius: 14px;
    box-shadow: var(--dw-shadow-2);
    opacity: 0; transform: translateY(-6px) scale(.98);
    pointer-events: none;
    transition: opacity .16s ease, transform .16s ease;
    z-index: 70;
}
html.v2 .dw-menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
html.v2 .dw-menu-label {
    padding: 8px 12px 6px;
    font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--dw-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-menu a,
html.v2 .dw-menu button {
    width: 100%;
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px;
    border-radius: 10px;
    font-size: 14px; color: var(--dw-text-2);
    background: transparent; border: 0; text-align: left; cursor: pointer;
}
html.v2 .dw-menu a:hover,
html.v2 .dw-menu button:hover { background: var(--dw-surface-2); color: var(--dw-text); }
html.v2 .dw-menu .dw-ico { width: 16px; height: 16px; opacity: .75; }
html.v2 .dw-menu .mdi { font-size: 17px; width: 17px; opacity: .75; }
html.v2 .dw-menu-sep { height: 1px; margin: 6px 8px; background: var(--dw-border); }

/* --- body: rail + content --- */
html.v2 .dw-body { display: flex; flex: 1; min-height: 0; align-items: stretch; }

/* The rail carries the same dark chrome as the top bar, so the two read as
   one frame around the content in both themes. */
html.v2 .dw-rail {
    flex: none;
    width: var(--dw-rail-w);
    background: var(--dw-rail);
    border-right: 1px solid var(--dw-rail-line);
    color: var(--dw-rail-text);
    display: flex; flex-direction: column;
    position: sticky;
    top: var(--dw-topbar-h);
    align-self: flex-start;
    height: calc(100vh - var(--dw-topbar-h));
    transition: width .18s ease;
    z-index: 40;
}
html.v2 .dw-rail-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 12px 12px 18px; }
html.v2 .dw-rail-scroll { scrollbar-color: rgba(255, 255, 255, .18) transparent; }
html.v2 .dw-rail-scroll::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .18); }
html.v2 .dw-rail-foot {
    padding: 12px 16px;
    border-top: 1px solid var(--dw-rail-line);
    font-size: 11.5px; color: var(--dw-rail-muted);
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    white-space: nowrap;
}

html.v2 .dw-rail-group {
    padding: 16px 12px 6px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
    color: var(--dw-rail-muted);
    opacity: .82;
    white-space: nowrap; overflow: hidden;
}
html.v2 .dw-rail-scroll > .dw-nav:first-child { margin-top: 2px; }

/* status card above the version line */
html.v2 .dw-rail-status {
    margin: 0 12px 12px;
    padding: 10px 12px;
    display: flex; align-items: flex-start; gap: 9px;
    border-radius: var(--dw-r);
    background: rgba(255, 255, 255, .05);
    border: 1px solid var(--dw-rail-line);
    font-size: 12px; line-height: 1.35;
    color: var(--dw-rail-muted);
}
html.v2 .dw-rail-status b { display: block; color: var(--dw-rail-text); font-weight: 600; }
html.v2 .dw-rail-status span span { display: block; margin-top: 1px; }
html.v2 .dw-rail-status-dot {
    width: 8px; height: 8px; border-radius: 50%; flex: none; margin-top: 4px;
    background: var(--dw-rail-muted);
}
html.v2 .dw-rail-status.is-good .dw-rail-status-dot { background: #35d68c; animation: dwPulse 2.6s ease-out infinite; }
html.v2 .dw-rail-status.is-warn .dw-rail-status-dot { background: #f0b429; }
html.v2 .dw-rail-status.is-bad  .dw-rail-status-dot { background: #f47272; }
html.v2 .dw-rail-status.is-sleep .dw-rail-status-dot { background: #8fa2c2; }
html.v2.dw-rail-mini .dw-rail-status { padding: 10px 0; justify-content: center; }
/* Hide the text, keep the dot — it is the whole point of the collapsed state. */
html.v2.dw-rail-mini .dw-rail-status > span:not(.dw-rail-status-dot) { display: none; }
html.v2.dw-rail-mini .dw-rail-status-dot { margin-top: 0; }
html.v2 .dw-nav { list-style: none; margin: 0; padding: 0; }
html.v2 .dw-nav > li { margin: 0 0 2px; }
html.v2 .dw-nav > li > a {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 12px;
    border-radius: 10px;
    color: var(--dw-rail-muted);
    font-size: 13.5px; font-weight: 500;
    transition: background .14s, color .14s;
    position: relative;
}
html.v2 .dw-nav > li > a:hover { background: var(--dw-rail-hover); color: var(--dw-rail-text); }
html.v2 .dw-nav-icon {
    width: 22px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--dw-rail-muted);
}
html.v2 .dw-nav-icon .mdi { font-size: 19px; line-height: 1; }
html.v2 .dw-nav-icon .mdi::before { font-size: 19px; }
html.v2 .dw-nav-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.v2 .dw-nav-sub {
    display: block;
    font-size: 11px; font-weight: 600;
    color: var(--dw-accent-2);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-nav > li.is-active > a {
    background: rgba(240, 160, 30, .14);
    color: var(--dw-accent);
    font-weight: 600;
}
html.v2 .dw-nav > li.is-active > a .dw-nav-icon { color: var(--dw-accent); }

/* trailing count bubble */
html.v2 .dw-nav-count {
    margin-left: auto; flex: none;
    font-size: 11px; font-weight: 650;
    padding: 1px 7px; border-radius: 999px;
    background: rgba(255, 255, 255, .09);
    color: var(--dw-rail-text);
}
html.v2 .dw-nav > li.is-active > a .dw-nav-count { background: rgba(240, 160, 30, .22); color: var(--dw-accent); }
html.v2.dw-rail-mini .dw-nav-count { display: none; }
html.v2 .dw-nav > li.is-active > a::before {
    content: '';
    position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
    width: 3px; height: 20px; border-radius: 0 3px 3px 0;
    background: var(--dw-accent);
}

/* collapsed rail */
html.v2.dw-rail-mini .dw-rail { width: var(--dw-rail-w-mini); }
html.v2.dw-rail-mini .dw-rail-scroll { padding: 14px 10px; }
html.v2.dw-rail-mini .dw-nav-title,
html.v2.dw-rail-mini .dw-rail-group,
html.v2.dw-rail-mini .dw-rail-foot span { display: none; }
/* With the group headings hidden, a hairline keeps the sections apart. */
html.v2.dw-rail-mini .dw-rail-group + .dw-nav { border-top: 1px solid var(--dw-rail-line); padding-top: 8px; margin-top: 8px; }
/* .dw-rail-scroll drops to 10px padding when collapsed, and clips at its
   padding box — so the active marker has to move with it. */
html.v2.dw-rail-mini .dw-nav > li.is-active > a::before { left: -10px; }
html.v2.dw-rail-mini .dw-nav > li > a { justify-content: center; padding: 11px 0; }
html.v2.dw-rail-mini .dw-rail-foot { justify-content: center; }
/* mdi-menu-open points at the rail it closes; flipped, it points out again. */
html.v2 #dw-rail-toggle .mdi { transition: transform .18s ease; }
html.v2.dw-rail-mini #dw-rail-toggle .mdi { transform: rotate(180deg); }

/* --- content --- */
html.v2 .dw-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
html.v2 .dw-content { padding: clamp(16px, 2.2vw, 28px); flex: 1; }
html.v2 .dw-content-wide { max-width: none; }
html.v2 .dw-content-narrow { max-width: 940px; }

html.v2 .dw-page-head {
    display: flex; flex-wrap: wrap; align-items: flex-end;
    justify-content: space-between; gap: 12px 24px;
    margin-bottom: clamp(16px, 2vw, 24px);
}
html.v2 .dw-page-title { margin: 0; font-size: clamp(21px, 2.6vw, 28px); font-weight: 650; letter-spacing: -.022em; }
html.v2 .dw-page-sub { margin: 6px 0 0; font-size: 13.5px; color: var(--dw-muted); }
html.v2 .dw-page-sub b { color: var(--dw-text-2); font-weight: 600; }
html.v2 .dw-page-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

html.v2 .dw-crumbs { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--dw-muted); margin-bottom: 8px; }
html.v2 .dw-crumbs a { color: var(--dw-muted); }
html.v2 .dw-crumbs a:hover { color: var(--dw-text-2); }
html.v2 .dw-crumbs .dw-ico { width: 13px; height: 13px; opacity: .6; }

/* section header with rule */
html.v2 .dw-section { margin: 0 0 32px; }
html.v2 .dw-section-head { display: flex; align-items: center; gap: 11px; margin: 0 0 14px; }
html.v2 .dw-section-ico {
    width: 34px; height: 34px; border-radius: 11px; flex: none;
    display: grid; place-items: center;
    background: var(--dw-surface); border: 1px solid var(--dw-border);
    color: var(--dw-accent-2); box-shadow: var(--dw-shadow-1);
}
html.v2[data-dw-theme="dark"] .dw-section-ico { color: var(--dw-accent); }
html.v2 .dw-section-ico .mdi { font-size: 19px; line-height: 1; }
html.v2 .dw-section-title {
    margin: 0; font-size: 12.5px; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase; color: var(--dw-text-2);
}
html.v2 .dw-section-count {
    font-size: 11.5px; font-weight: 650; color: var(--dw-muted);
    background: var(--dw-surface); border: 1px solid var(--dw-border);
    border-radius: 999px; padding: 2px 9px;
}
html.v2 .dw-section-rule { flex: 1; height: 1px; background: linear-gradient(90deg, var(--dw-border), transparent); }

/* --- mobile rail --- */
html.v2 .dw-rail-backdrop {
    position: fixed; top: var(--dw-topbar-h); right: 0; bottom: 0; left: 0; z-index: 39;
    background: rgba(9, 12, 17, .5);
    opacity: 0; pointer-events: none; transition: opacity .2s;
}
@media (max-width: 959px) {
    html.v2 .dw-rail {
        /* Below the z-60 opaque top bar, not behind it. */
        position: fixed; top: var(--dw-topbar-h); left: 0; bottom: 0;
        height: calc(100vh - var(--dw-topbar-h));
        transform: translateX(-100%);
        transition: transform .22s cubic-bezier(.2, .7, .3, 1);
        box-shadow: var(--dw-shadow-3);
        width: min(300px, 86vw);
    }
    html.v2.dw-rail-open .dw-rail { transform: none; }
    html.v2.dw-rail-open .dw-rail-backdrop { opacity: 1; pointer-events: auto; }
    html.v2.dw-rail-mini .dw-rail { width: min(300px, 86vw); }
    html.v2.dw-rail-mini .dw-nav-title,
    html.v2.dw-rail-mini .dw-rail-group,
    html.v2.dw-rail-mini .dw-rail-foot span { display: initial; }
    html.v2.dw-rail-mini .dw-nav > li > a { justify-content: flex-start; padding: 9px 12px; }
    html.v2.dw-rail-mini .dw-rail-group + .dw-nav { border-top: 0; padding-top: 0; margin-top: 0; }
    html.v2.dw-rail-mini .dw-nav-count { display: inline-block; }
    html.v2.dw-rail-mini .dw-rail-status { padding: 10px 12px; justify-content: flex-start; }
    html.v2.dw-rail-mini .dw-rail-status > span:not(.dw-rail-status-dot) { display: block; }
    html.v2 .dw-topbar-title { display: none; }
}
@media (min-width: 960px) {
    html.v2 .dw-rail-toggle-mobile { display: none; }
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
html.v2 .uk-button,
html.v2 .dw-btn {
    /* Border-box, or .dw-btn-block's width:100% lands 34px (padding + border)
       wider than its container and hangs off the right of the panel. The
       heights below are the old content heights plus the 1px borders, so
       nothing changes size. */
    box-sizing: border-box;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    height: 40px; padding: 0 16px;
    border: 1px solid transparent;
    border-radius: var(--dw-r-sm);
    font-family: var(--dw-font);
    font-size: 13.5px; font-weight: 600; line-height: 1;
    letter-spacing: 0;
    text-transform: none;
    cursor: pointer;
    transition: background .16s, border-color .16s, color .16s, box-shadow .16s, transform .08s;
    box-shadow: none;
    white-space: nowrap;
    vertical-align: middle;
}
html.v2 .uk-button:active,
html.v2 .dw-btn:active { transform: translateY(1px); }
html.v2 .uk-button .mdi { font-size: 17px; line-height: 1; }
html.v2 .uk-button .dw-ico,
html.v2 .dw-btn .dw-ico { width: 16px; height: 16px; }

/* default / secondary */
html.v2 .uk-button-default,
html.v2 .dw-btn {
    background: var(--dw-surface);
    border-color: var(--dw-border-strong);
    color: var(--dw-text-2);
}
html.v2 .uk-button-default:hover,
html.v2 .uk-button-default:focus,
html.v2 .dw-btn:hover {
    background: var(--dw-surface-2);
    border-color: var(--dw-muted);
    color: var(--dw-text);
}

/* primary */
html.v2 .uk-button-primary,
html.v2 .dw-btn-primary {
    background: var(--dw-accent);
    border-color: var(--dw-accent);
    color: var(--dw-on-accent);
    box-shadow: 0 8px 20px -12px rgba(240, 160, 30, .9);
}
html.v2 .uk-button-primary:hover,
html.v2 .uk-button-primary:focus,
html.v2 .dw-btn-primary:hover {
    background: var(--dw-accent-2);
    border-color: var(--dw-accent-2);
    color: #fff;
}

/* secondary (dark) */
html.v2 .uk-button-secondary,
html.v2 .dw-btn-dark {
    background: var(--dw-text);
    border-color: var(--dw-text);
    color: var(--dw-surface);
}
html.v2 .uk-button-secondary:hover,
html.v2 .uk-button-secondary:focus,
html.v2 .dw-btn-dark:hover { background: var(--dw-text-2); border-color: var(--dw-text-2); color: #fff; }

/* danger */
html.v2 .uk-button-danger,
html.v2 .dw-btn-danger {
    background: var(--dw-bad);
    border-color: var(--dw-bad);
    color: #fff;
}
html.v2 .uk-button-danger:hover,
html.v2 .uk-button-danger:focus,
html.v2 .dw-btn-danger:hover { filter: brightness(.93); color: #fff; }

/* text / link */
html.v2 .uk-button-text,
html.v2 .uk-button-link {
    height: auto; padding: 0;
    background: none; border: 0;
    color: var(--dw-accent-2);
    text-transform: none;
    font-size: 13.5px;
}
html.v2 .uk-button-text::before { display: none; }
html.v2 .uk-button-text:hover,
html.v2 .uk-button-link:hover { color: var(--dw-accent); text-decoration: none; }

/* sizes */
html.v2 .uk-button-small { height: 32px; padding: 0 11px; font-size: 12.5px; border-radius: 7px; }
html.v2 .uk-button-small .mdi { font-size: 15px; }
html.v2 .uk-button-large { height: 46px; padding: 0 22px; font-size: 15px; border-radius: var(--dw-r); }

html.v2 .uk-button:disabled,
html.v2 .uk-button.uk-disabled,
html.v2 .dw-btn:disabled {
    opacity: .5; cursor: not-allowed; transform: none;
    box-shadow: none;
}

html.v2 .uk-button-group { display: inline-flex; border-radius: var(--dw-r-sm); overflow: hidden; }
html.v2 .uk-button-group > .uk-button { border-radius: 0; }
html.v2 .uk-button-group > .uk-button:first-child { border-radius: var(--dw-r-sm) 0 0 var(--dw-r-sm); }
html.v2 .uk-button-group > .uk-button:last-child { border-radius: 0 var(--dw-r-sm) var(--dw-r-sm) 0; }

/* icon-only action button used in tables */
html.v2 .dw-btn-icon {
    width: 34px; height: 34px; padding: 0;
    border-radius: var(--dw-r-sm);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    color: var(--dw-text-2);
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
html.v2 .dw-btn-icon:hover { background: var(--dw-surface-3); color: var(--dw-text); border-color: var(--dw-border-strong); }
html.v2 .dw-btn-icon .mdi { font-size: 17px; line-height: 1; }
html.v2 .dw-btn-icon.is-danger:hover { background: var(--dw-bad-soft); border-color: var(--dw-bad); color: var(--dw-bad); }

/* --------------------------------------------------------------------------
   5. Forms
   -------------------------------------------------------------------------- */
html.v2 .uk-form-label,
html.v2 .dw-label {
    display: block;
    font-size: 12.5px; font-weight: 600;
    color: var(--dw-text-2);
    margin-bottom: 6px;
    text-transform: none;
    letter-spacing: 0;
}
html.v2 .uk-form-controls { margin-top: 0; }

html.v2 .uk-input,
html.v2 .uk-select,
html.v2 .uk-textarea,
html.v2 .dw-field {
    /* app.css gives the uk-* ones border-box; .dw-field is ours and needs it
       too, or width:100% plus the padding overflows the field's container. */
    box-sizing: border-box;
    width: 100%;
    height: 40px;
    padding: 0 12px;
    font-family: var(--dw-font);
    font-size: 14px;
    color: var(--dw-text);
    background-color: var(--dw-surface);
    background-image: none;
    border: 1px solid var(--dw-border-strong);
    border-radius: var(--dw-r-sm);
    box-shadow: none;
    transition: border-color .16s, box-shadow .16s, background-color .16s;
}
html.v2 textarea.uk-textarea,
html.v2 .uk-textarea { height: auto; min-height: 88px; padding: 10px 12px; line-height: 1.5; }
html.v2 select.uk-select {
    padding-right: 34px;
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2378849a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9.5 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
}
html.v2 select.uk-select:not([size]):not([multiple]) { height: 40px; }
html.v2 .uk-input:focus,
html.v2 .uk-select:focus,
html.v2 .uk-textarea:focus,
html.v2 .dw-field:focus {
    outline: none;
    background-color: var(--dw-surface);
    border-color: var(--dw-accent);
    box-shadow: 0 0 0 3px var(--dw-accent-soft);
    color: var(--dw-text);
}
html.v2 .uk-input::placeholder,
html.v2 .uk-textarea::placeholder { color: var(--dw-muted); opacity: 1; }
html.v2 .uk-input:disabled,
html.v2 .uk-select:disabled,
html.v2 .uk-textarea:disabled { background: var(--dw-surface-2); color: var(--dw-muted); cursor: not-allowed; }

html.v2 .uk-form-danger,
html.v2 .uk-input.uk-form-danger,
html.v2 .uk-select.uk-form-danger,
html.v2 .uk-textarea.uk-form-danger {
    border-color: var(--dw-bad);
    box-shadow: 0 0 0 3px var(--dw-bad-soft);
}
html.v2 .uk-form-success { border-color: var(--dw-good); }
html.v2 .uk-form-small { height: 34px; font-size: 13px; padding: 0 10px; }
html.v2 .uk-form-large { height: 46px; font-size: 15px; }
html.v2 .uk-form-blank { border-color: transparent; background: transparent; }

html.v2 .dw-hint { display: block; font-size: 12px; color: var(--dw-muted); margin-top: 5px; }
html.v2 .dw-error,
html.v2 .uk-text-danger { color: var(--dw-bad-text); }
html.v2 .dw-error { display: block; font-size: 12px; margin-top: 5px; font-weight: 500; }

/* checkbox / radio */
html.v2 .uk-checkbox,
html.v2 .uk-radio {
    width: 18px; height: 18px;
    margin-top: -3px; margin-right: 8px;
    border: 1.5px solid var(--dw-border-strong);
    background-color: var(--dw-surface);
    background-image: none;
    transition: background-color .14s, border-color .14s;
}
html.v2 .uk-checkbox { border-radius: 5px; }
html.v2 .uk-radio { border-radius: 50%; }
html.v2 .uk-checkbox:focus,
html.v2 .uk-radio:focus { border-color: var(--dw-accent); box-shadow: 0 0 0 3px var(--dw-accent-soft); outline: none; }
html.v2 .uk-checkbox:checked,
html.v2 .uk-radio:checked,
html.v2 .uk-checkbox:indeterminate {
    background-color: var(--dw-accent);
    border-color: var(--dw-accent);
}
html.v2 .uk-checkbox:checked {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23231806' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6.5 9.5 17 4 11.5'/%3E%3C/svg%3E");
}
html.v2 .uk-checkbox:indeterminate {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23231806' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E");
}
html.v2 .uk-radio:checked {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='5' fill='%23231806'/%3E%3C/svg%3E");
}

/* switch */
html.v2 .dw-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
html.v2 .dw-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
html.v2 .dw-switch-track {
    width: 40px; height: 22px; border-radius: 999px; flex: none;
    background: var(--dw-border-strong);
    position: relative;
    transition: background .18s;
}
html.v2 .dw-switch-track::after {
    content: ''; position: absolute; top: 3px; left: 3px;
    width: 16px; height: 16px; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
    transition: transform .18s;
}
html.v2 .dw-switch input:checked + .dw-switch-track { background: var(--dw-accent); }
html.v2 .dw-switch input:checked + .dw-switch-track::after { transform: translateX(18px); }
html.v2 .dw-switch input:focus-visible + .dw-switch-track { box-shadow: 0 0 0 3px var(--dw-accent-soft); }

/* file input */
html.v2 .dw-file {
    display: flex; align-items: center; gap: 12px;
    padding: 14px;
    border: 1px dashed var(--dw-border-strong);
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
    color: var(--dw-text-2);
    font-size: 13.5px;
}
html.v2 input[type="file"] { font-size: 13px; color: var(--dw-text-2); max-width: 100%; }
html.v2 input[type="file"]::file-selector-button {
    height: 32px; padding: 0 12px; margin-right: 10px;
    border: 1px solid var(--dw-border-strong);
    border-radius: 7px;
    background: var(--dw-surface);
    color: var(--dw-text-2);
    font-family: var(--dw-font); font-size: 12.5px; font-weight: 600;
    cursor: pointer;
}
html.v2 input[type="file"]::file-selector-button:hover { background: var(--dw-surface-3); }

/* search field with leading icon */
html.v2 .dw-search { position: relative; }
html.v2 .dw-search .uk-input,
html.v2 .dw-search input { padding-left: 36px; }
html.v2 .dw-search > .dw-ico,
html.v2 .dw-search > .mdi {
    position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; font-size: 16px;
    /* The icon font inherits the 1.5 line-height, so the glyph is drawn low
       inside its 16px box and reads as bottom-aligned in the field. Centring
       it in a flex box with line-height 1 puts it on the optical middle. */
    display: flex; align-items: center; justify-content: center; line-height: 1;
    color: var(--dw-muted); pointer-events: none;
}

/* form layout helpers */
html.v2 .dw-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px 18px; }
html.v2 .dw-field-row { margin-bottom: 16px; }
html.v2 .dw-field-row:last-child { margin-bottom: 0; }
html.v2 .dw-form-actions {
    display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
    padding-top: 4px;
}

html.v2 .dw-fieldset { border: 0; margin: 0 0 28px; padding: 0; min-width: 0; }
html.v2 .dw-fieldset:last-child { margin-bottom: 0; }
html.v2 .dw-fieldset-title {
    font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--dw-muted);
    margin: 0 0 4px;
}
html.v2 .dw-fieldset-note { font-size: 12.5px; color: var(--dw-muted); margin: 0 0 14px; }
html.v2 .dw-fieldset-title + .dw-check-grid,
html.v2 .dw-fieldset-title + .dw-form-grid,
html.v2 .dw-fieldset-title + .dw-field-row { margin-top: 14px; }

/* selectable checkbox / radio cards */
html.v2 .dw-check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
html.v2 .dw-check-grid.is-tight { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
html.v2 .dw-check-stack { display: grid; gap: 10px; }
html.v2 .dw-check {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 13px;
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-sm);
    background: var(--dw-surface-2);
    color: var(--dw-text-2);
    font-size: 13.5px; font-weight: 500;
    cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
html.v2 .dw-check:hover { border-color: var(--dw-border-strong); color: var(--dw-text); }
html.v2 .dw-check input { margin: 0 !important; flex: none; }
html.v2 .dw-check:has(input:checked) {
    border-color: var(--dw-accent);
    background: var(--dw-accent-soft);
    color: var(--dw-text);
}
html.v2 .dw-check:focus-within { box-shadow: 0 0 0 3px var(--dw-accent-soft); }
html.v2 .dw-check-note { display: block; font-size: 12px; color: var(--dw-muted); font-weight: 400; margin-top: 2px; }

/* range slider */
html.v2 input[type="range"],
html.v2 .uk-range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 22px;
    padding: 0;
    background: transparent;
    border: 0;
}
html.v2 input[type="range"]::-webkit-slider-runnable-track,
html.v2 .uk-range::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: 999px;
    background: var(--dw-surface-3);
    border: 1px solid var(--dw-border);
}
html.v2 input[type="range"]::-webkit-slider-thumb,
html.v2 .uk-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px; height: 16px;
    margin-top: -6px;
    border-radius: 50%;
    background: var(--dw-accent);
    border: 2px solid var(--dw-surface);
    box-shadow: 0 1px 4px rgba(13, 17, 23, .3);
    cursor: pointer;
}
html.v2 input[type="range"]::-moz-range-track,
html.v2 .uk-range::-moz-range-track {
    height: 6px; border-radius: 999px;
    background: var(--dw-surface-3); border: 1px solid var(--dw-border);
}
html.v2 input[type="range"]::-moz-range-thumb,
html.v2 .uk-range::-moz-range-thumb {
    width: 14px; height: 14px; border-radius: 50%;
    background: var(--dw-accent); border: 2px solid var(--dw-surface);
    cursor: pointer;
}
html.v2 input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--dw-accent-soft); }
html.v2 output { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--dw-text-2); }

/* preset picker — the whole card is the radio's label */
html.v2 .dw-preset-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 12px;
}
html.v2 .dw-preset { position: relative; display: flex; cursor: pointer; }
html.v2 .dw-preset > input {
    position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
}
html.v2 .dw-preset-card {
    position: relative;
    display: flex; flex-direction: column; flex: 1 1 auto;
    padding: 16px 16px 14px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    box-shadow: var(--dw-shadow-1);
    transition: border-color .16s, box-shadow .16s, transform .16s;
}
html.v2 .dw-preset:hover .dw-preset-card {
    border-color: var(--dw-border-strong);
    transform: translateY(-2px);
    box-shadow: var(--dw-shadow-2);
}
html.v2 .dw-preset > input:focus-visible + .dw-preset-card { outline: 2px solid var(--dw-accent); outline-offset: 2px; }
html.v2 .dw-preset > input:checked + .dw-preset-card {
    border-color: var(--dw-accent);
    box-shadow: 0 0 0 1px var(--dw-accent), var(--dw-shadow-2);
}
html.v2 .dw-preset-eyebrow {
    display: block; margin: 0 0 4px; padding-right: 26px;
    font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--dw-muted);
}
html.v2 .dw-preset > input:checked + .dw-preset-card .dw-preset-eyebrow { color: var(--dw-accent-2); }
html.v2[data-dw-theme="dark"] .dw-preset > input:checked + .dw-preset-card .dw-preset-eyebrow { color: var(--dw-accent); }
html.v2 .dw-preset-name {
    display: block; margin: 0 0 7px;
    font-size: 16px; font-weight: 650; line-height: 1.2; letter-spacing: -.015em;
    color: var(--dw-text);
}
html.v2 .dw-preset-blurb {
    display: block; flex: 1 1 auto; margin: 0 0 14px;
    font-size: 12.5px; line-height: 1.5; color: var(--dw-muted);
}
html.v2 .dw-preset-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding-top: 11px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-preset-foot-label {
    font-size: 10px; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted); white-space: nowrap;
}
html.v2 .dw-meter { display: inline-flex; gap: 3px; flex: none; }
html.v2 .dw-meter span { width: 12px; height: 4px; border-radius: 2px; background: var(--dw-surface-3); }
html.v2 .dw-meter span.on { background: var(--dw-muted); }
html.v2 .dw-preset > input:checked + .dw-preset-card .dw-meter span.on { background: var(--dw-accent); }
html.v2 .dw-preset-tick {
    position: absolute; top: 13px; right: 13px;
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--dw-accent); color: var(--dw-on-accent);
    font-size: 13px;
    display: none; align-items: center; justify-content: center;
}
html.v2 .dw-preset > input:checked + .dw-preset-card .dw-preset-tick { display: inline-flex; }

/* --------------------------------------------------------------------------
   6. Cards & panels
   -------------------------------------------------------------------------- */
html.v2 .uk-card,
html.v2 .dw-card {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    color: var(--dw-text);
    transition: box-shadow .2s, border-color .2s, transform .2s;
}
html.v2 .uk-card-default,
html.v2 .uk-card-primary,
html.v2 .uk-card-secondary { background: var(--dw-surface); color: var(--dw-text); box-shadow: var(--dw-shadow-1); }
html.v2 .uk-card-hover:hover { box-shadow: var(--dw-shadow-2); border-color: var(--dw-border-strong); }

html.v2 .uk-card-header,
html.v2 .dw-card-head {
    padding: 16px 20px;
    border-bottom: 1px solid var(--dw-border);
    display: flex; align-items: center; gap: 12px;
    flex-wrap: wrap;
}
html.v2 .uk-card-body,
html.v2 .dw-card-body { padding: 20px; }
html.v2 .uk-card-footer,
html.v2 .dw-card-foot {
    padding: 14px 20px;
    border-top: 1px solid var(--dw-border);
    background: var(--dw-surface-2);
    border-radius: 0 0 var(--dw-r-lg) var(--dw-r-lg);
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
html.v2 .uk-card-title,
html.v2 .dw-card-title { margin: 0; font-size: 15.5px; font-weight: 600; letter-spacing: -.01em; }
html.v2 .uk-card-badge { border-radius: 999px; }
html.v2 .uk-card-small .uk-card-body { padding: 16px; }
html.v2 .uk-card-large .uk-card-body { padding: 28px; }

html.v2 .dw-card-title-wrap { flex: 1; min-width: 0; }
html.v2 .dw-card-note { margin: 3px 0 0; font-size: 12.5px; color: var(--dw-muted); }

/* stat tile */
html.v2 .dw-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; }
html.v2 .dw-stat {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    padding: 18px 20px;
    box-shadow: var(--dw-shadow-1);
    display: flex; align-items: flex-start; gap: 14px;
}
html.v2 .dw-stat-ico {
    width: 40px; height: 40px; border-radius: var(--dw-r); flex: none;
    display: grid; place-items: center;
    background: var(--dw-accent-soft); color: var(--dw-accent-2);
}
html.v2[data-dw-theme="dark"] .dw-stat-ico { color: var(--dw-accent); }
html.v2 .dw-stat-ico .mdi { font-size: 21px; line-height: 1; }
html.v2 .dw-stat-body { min-width: 0; }
html.v2 .dw-stat-label {
    font-size: 11.5px; font-weight: 650; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted); margin: 0 0 4px;
}
html.v2 .dw-stat-value { font-size: 26px; font-weight: 650; letter-spacing: -.02em; line-height: 1.1; }
html.v2 .dw-stat-note { font-size: 12.5px; color: var(--dw-muted); margin: 4px 0 0; }

/* labelled control strip (project / camera / date pickers) */
html.v2 .dw-tools {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px 16px;
    padding: 16px;
    margin-bottom: 20px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
}
html.v2 .dw-tool { min-width: 0; }
html.v2 .dw-tool-label {
    display: block;
    font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--dw-muted);
    margin-bottom: 6px;
}
html.v2 .dw-tool > div { display: flex; align-items: center; gap: 8px; }
html.v2 .dw-tool select.uk-select,
html.v2 .dw-tool input.uk-input { width: 100% !important; }
html.v2 .dw-tool a { color: var(--dw-accent-2); display: inline-flex; align-items: center; }
html.v2 .dw-tool > div > div { flex: none; width: auto !important; display: inline-flex !important; }

/* toolbar strip above content */
html.v2 .dw-toolbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    padding: 14px 16px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    margin-bottom: 20px;
}
html.v2 .dw-toolbar > .dw-toolbar-grow { flex: 1; min-width: 200px; }

/* --------------------------------------------------------------------------
   7. Tables
   -------------------------------------------------------------------------- */
html.v2 .dw-table-wrap {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    overflow: hidden;
}
html.v2 .dw-table-scroll { overflow-x: auto; }

html.v2 .uk-table {
    margin: 0;
    font-size: 13.5px;
    border-collapse: separate;
    border-spacing: 0;
    color: var(--dw-text);
    width: 100%;
}
html.v2 .uk-table th {
    padding: 11px 16px;
    background: var(--dw-surface-2);
    border-bottom: 1px solid var(--dw-border);
    color: var(--dw-muted);
    font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    vertical-align: middle;
}
html.v2 .uk-table td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--dw-border);
    vertical-align: middle;
    color: var(--dw-text-2);
}
html.v2 .uk-table tbody tr:last-child td { border-bottom: 0; }
html.v2 .uk-table tbody tr { transition: background .14s; }
html.v2 .uk-table-hover tbody tr:hover,
html.v2 .uk-table tbody tr:hover { background: var(--dw-surface-2); }
html.v2 .uk-table-striped tbody tr:nth-of-type(odd) { background: transparent; }
html.v2 .uk-table-striped tbody tr:nth-of-type(odd):hover { background: var(--dw-surface-2); }
html.v2 .uk-table-divider > :not(:first-child) > tr:first-child > * { border-top: 1px solid var(--dw-border); }
html.v2 .uk-table caption { color: var(--dw-muted); font-size: 12.5px; }
html.v2 .uk-table-small th,
html.v2 .uk-table-small td { padding: 8px 12px; }
html.v2 .uk-table a { color: var(--dw-accent-2); font-weight: 500; }
html.v2 .uk-table .dw-cell-strong { color: var(--dw-text); font-weight: 600; }
html.v2 .uk-table-actions,
html.v2 .uk-table td.dw-actions { white-space: nowrap; text-align: right; }
html.v2 .uk-table td.dw-actions > * + * { margin-left: 6px; }

/* DataTables (uikit skin) */
html.v2 .dataTables_wrapper { padding: 0; }
html.v2 .dataTables_wrapper .dataTables_length,
html.v2 .dataTables_wrapper .dataTables_filter,
html.v2 .dataTables_wrapper .dataTables_info,
html.v2 .dataTables_wrapper .dataTables_paginate {
    font-size: 13px;
    color: var(--dw-muted);
    padding: 12px 16px;
}
html.v2 .dataTables_wrapper .dataTables_filter input,
html.v2 .dataTables_wrapper .dataTables_length select {
    height: 34px; padding: 0 10px; margin-left: 8px;
    border: 1px solid var(--dw-border-strong);
    border-radius: var(--dw-r-sm);
    background: var(--dw-surface);
    color: var(--dw-text);
    font-family: var(--dw-font); font-size: 13px;
}
html.v2 .dataTables_wrapper .dataTables_filter input:focus,
html.v2 .dataTables_wrapper .dataTables_length select:focus {
    outline: none; border-color: var(--dw-accent); box-shadow: 0 0 0 3px var(--dw-accent-soft);
}
html.v2 table.dataTable thead th { cursor: pointer; position: relative; padding-right: 26px; }
html.v2 table.dataTable thead th.sorting::after,
html.v2 table.dataTable thead th.sorting_asc::after,
html.v2 table.dataTable thead th.sorting_desc::after {
    content: '';
    position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
    width: 12px; height: 12px;
    background-repeat: no-repeat; background-position: center;
    opacity: .45;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2378849a' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='m7 10 5-5 5 5M7 14l5 5 5-5'/%3E%3C/svg%3E");
}
html.v2 table.dataTable thead th.sorting_asc::after {
    opacity: 1;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23da7d02' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='m6 14 6-6 6 6'/%3E%3C/svg%3E");
}
html.v2 table.dataTable thead th.sorting_desc::after {
    opacity: 1;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23da7d02' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='m6 10 6 6 6-6'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   8. Pagination
   -------------------------------------------------------------------------- */
html.v2 .uk-pagination { margin: 0; display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
html.v2 .uk-pagination > * { padding: 0; }
html.v2 .uk-pagination > * > a,
html.v2 .uk-pagination > * > span {
    min-width: 32px; height: 32px; padding: 0 9px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--dw-border);
    border-radius: 8px;
    background: var(--dw-surface);
    color: var(--dw-text-2);
    font-size: 13px; font-weight: 600;
}
html.v2 .uk-pagination > * > a:hover { background: var(--dw-surface-2); color: var(--dw-text); border-color: var(--dw-border-strong); }
html.v2 .uk-pagination > .uk-active > a,
html.v2 .uk-pagination > .uk-active > span,
html.v2 .uk-pagination > .active > a {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent);
}
html.v2 .uk-pagination > .uk-disabled > * { opacity: .45; }

/* --------------------------------------------------------------------------
   9. Alerts & notifications
   -------------------------------------------------------------------------- */
html.v2 .uk-alert,
html.v2 .dw-alert {
    position: relative;
    display: flex; align-items: flex-start; gap: 12px;
    margin: 0 0 18px;
    padding: 14px 16px;
    border: 1px solid var(--dw-border);
    border-left: 3px solid var(--dw-muted);
    border-radius: var(--dw-r);
    background: var(--dw-surface);
    color: var(--dw-text-2);
    font-size: 13.5px;
    box-shadow: var(--dw-shadow-1);
}
html.v2 .uk-alert > :last-child,
html.v2 .uk-alert p { margin-bottom: 0; }
html.v2 .uk-alert-close {
    position: absolute; top: 12px; right: 12px;
    color: var(--dw-muted); opacity: .8;
}
html.v2 .uk-alert-close:hover { color: var(--dw-text); opacity: 1; }

html.v2 .uk-alert-primary { background: var(--dw-info-soft); border-color: transparent; border-left-color: var(--dw-info); color: var(--dw-text); }
html.v2 .uk-alert-success { background: var(--dw-good-soft); border-color: transparent; border-left-color: var(--dw-good); color: var(--dw-text); }
html.v2 .uk-alert-warning { background: var(--dw-warn-soft); border-color: transparent; border-left-color: var(--dw-warn); color: var(--dw-text); }
html.v2 .uk-alert-danger  { background: var(--dw-bad-soft);  border-color: transparent; border-left-color: var(--dw-bad);  color: var(--dw-text); }

html.v2 .uk-notification-message {
    background: var(--dw-surface);
    color: var(--dw-text);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    box-shadow: var(--dw-shadow-2);
    font-size: 13.5px;
    padding: 14px 16px;
}
html.v2 .uk-notification-message-primary { border-left: 3px solid var(--dw-info); }
html.v2 .uk-notification-message-success { border-left: 3px solid var(--dw-good); }
html.v2 .uk-notification-message-warning { border-left: 3px solid var(--dw-warn); }
html.v2 .uk-notification-message-danger  { border-left: 3px solid var(--dw-bad); }

/* toast used by v2.js */
html.v2 .dw-toast {
    position: fixed; z-index: 300; left: 50%; top: 18px;
    transform: translate(-50%, -14px);
    padding: 11px 16px; border-radius: var(--dw-r);
    font-size: 13.5px; font-weight: 500;
    background: var(--dw-surface); color: var(--dw-text);
    border: 1px solid var(--dw-border); box-shadow: var(--dw-shadow-2);
    opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
    max-width: min(520px, 90vw);
}
html.v2 .dw-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
html.v2 .dw-toast.is-error { border-left: 3px solid var(--dw-bad); }
html.v2 .dw-toast.is-success { border-left: 3px solid var(--dw-good); }

/* download progress panel — dwDownload() in v2.js. Stacks bottom-right, one
   card per download in flight. */
html.v2 .dw-dl-stack {
    position: fixed; z-index: 280; right: 24px; bottom: 24px;
    display: flex; flex-direction: column; gap: 12px;
    width: min(448px, calc(100vw - 32px));
    pointer-events: none;
}
html.v2 .dw-dl {
    pointer-events: auto;
    display: flex; gap: 14px;
    padding: 18px 18px 18px 20px;
    border-radius: var(--dw-r-lg);
    background: var(--dw-surface); color: var(--dw-text);
    border: 1px solid var(--dw-border); box-shadow: var(--dw-shadow-3);
    animation: dw-dl-in .22s ease-out;
}
/* Centred on the title's first line; the glyph is taller than the line box. */
html.v2 .dw-dl-icon {
    flex: none; display: flex; align-items: center; justify-content: center;
    width: 32px; height: 26px; font-size: 32px; color: var(--dw-accent-text);
}
html.v2 .dw-dl-body { flex: 1; min-width: 0; }
html.v2 .dw-dl-head { display: flex; align-items: flex-start; gap: 12px; }
html.v2 .dw-dl-title { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; line-height: 26px; }
html.v2 .dw-dl-close {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; margin: -1px -6px 0 0; padding: 0;
    border: 0; border-radius: var(--dw-r-sm); background: transparent;
    color: var(--dw-text-2); font-size: 18px; cursor: pointer;
}
html.v2 .dw-dl-close:hover { background: var(--dw-surface-3); color: var(--dw-text); }
html.v2 .dw-dl-close:focus-visible { outline: 2px solid var(--dw-accent); outline-offset: 1px; }
html.v2 .dw-dl-sub {
    font-size: 13px; color: var(--dw-text-2);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-dl-meter { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
html.v2 .dw-dl-bar {
    position: relative; flex: 1; height: 8px; overflow: hidden;
    border-radius: 999px; background: var(--dw-surface-3);
}
html.v2 .dw-dl-bar > span {
    position: absolute; top: 0; bottom: 0; left: 0; width: 0;
    border-radius: inherit; background: var(--dw-accent);
    transition: width .3s ease;
}
html.v2 .dw-dl-bar.is-indeterminate > span { width: 38%; transition: none; animation: dw-dl-slide 1.4s ease-in-out infinite; }
html.v2 .dw-dl-pct {
    min-width: 38px; text-align: right;
    font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums;
}
html.v2 .dw-dl-pct:empty { display: none; }
html.v2 .dw-dl-detail { margin-top: 10px; font-size: 12.5px; color: var(--dw-text-2); font-variant-numeric: tabular-nums; }
html.v2 .dw-dl.is-done .dw-dl-icon { color: var(--dw-good-text); }
html.v2 .dw-dl.is-done .dw-dl-bar > span { background: var(--dw-good); }
html.v2 .dw-dl.is-error .dw-dl-icon { color: var(--dw-bad-text); }
html.v2 .dw-dl.is-error .dw-dl-bar > span { background: var(--dw-bad); }
@keyframes dw-dl-in { from { opacity: 0; transform: translateY(10px); } }
@keyframes dw-dl-slide { from { left: -38%; } to { left: 100%; } }
@media (prefers-reduced-motion: reduce) {
    /* A frozen slider would read as a stalled bar; a dim full one reads as "working". */
    html.v2 .dw-dl-bar.is-indeterminate > span { left: 0; width: 100%; opacity: .35; }
}
@media (max-width: 640px) {
    html.v2 .dw-dl-stack { right: 16px; bottom: 16px; }
    html.v2 .dw-dl { padding: 16px; gap: 12px; }
}

/* --------------------------------------------------------------------------
   10. Modals & dropdowns
   -------------------------------------------------------------------------- */
/* UIkit adds .uk-modal (display: none, position: fixed) only when its script
   runs, at the end of the page load. Until then a dialog in the markup is an
   ordinary block: invisible, because its panel starts at opacity 0, but still
   taking up room. The feature-request dialog sits in the rail's flex row, so
   it squeezed .dw-main into the right half of the page until load. */
html.v2 [uk-modal]:not(.uk-modal) { display: none; }
html.v2 .uk-modal { background: rgba(9, 12, 17, .58); backdrop-filter: blur(2px); }
html.v2 .uk-modal-dialog {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-xl);
    box-shadow: var(--dw-shadow-3);
    color: var(--dw-text);
    overflow: hidden;
}
html.v2 .uk-modal-header {
    padding: 18px 24px;
    background: var(--dw-surface);
    border-bottom: 1px solid var(--dw-border);
}
html.v2 .uk-modal-title { margin: 0; font-size: 18px; font-weight: 650; letter-spacing: -.015em; }
html.v2 .uk-modal-body { padding: 24px; }
html.v2 .uk-modal-footer {
    padding: 16px 24px;
    background: var(--dw-surface-2);
    border-top: 1px solid var(--dw-border);
    display: flex; gap: 10px; align-items: center; justify-content: flex-end;
    flex-wrap: wrap;
}
html.v2 .uk-modal-close-default,
html.v2 .uk-modal-close-outside {
    width: 32px; height: 32px; border-radius: 9px;
    display: grid; place-items: center;
    color: var(--dw-muted);
    background: transparent; border: 0;
    top: 16px; right: 16px;
}
html.v2 .uk-modal-close-default:hover { background: var(--dw-surface-2); color: var(--dw-text); }

html.v2 .uk-dropdown,
html.v2 .uk-navbar-dropdown {
    background: var(--dw-surface);
    color: var(--dw-text);
    border: 1px solid var(--dw-border);
    border-radius: 14px;
    box-shadow: var(--dw-shadow-2);
    padding: 6px;
    min-width: 210px;
}
html.v2 .uk-dropdown-nav > li > a,
html.v2 .uk-navbar-dropdown-nav > li > a,
html.v2 .uk-nav-navbar > li > a {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px;
    border-radius: 10px;
    color: var(--dw-text-2);
    font-size: 13.5px;
}
html.v2 .uk-dropdown-nav > li > a:hover,
html.v2 .uk-navbar-dropdown-nav > li > a:hover,
html.v2 .uk-nav-navbar > li > a:hover { background: var(--dw-surface-2); color: var(--dw-text); }
html.v2 .uk-nav-divider { border-top: 1px solid var(--dw-border); margin: 6px 8px; }
html.v2 .uk-nav-header {
    padding: 8px 12px 6px;
    font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--dw-muted);
}

html.v2 .uk-tooltip {
    background: var(--dw-text);
    color: var(--dw-surface);
    border-radius: 8px;
    padding: 6px 9px;
    font-size: 12px;
    box-shadow: var(--dw-shadow-2);
}

/* --------------------------------------------------------------------------
   11. Badges, labels, chips
   -------------------------------------------------------------------------- */
html.v2 .uk-badge {
    height: 20px; min-width: 20px;
    background: var(--dw-accent); color: var(--dw-on-accent);
    font-size: 11.5px; font-weight: 700;
    border-radius: 999px;
}
html.v2 .uk-label,
html.v2 .dw-tag {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--dw-surface-3);
    color: var(--dw-text-2);
    font-size: 11.5px; font-weight: 650;
    letter-spacing: .01em; text-transform: none;
    line-height: 1.45;
    white-space: nowrap;
}
html.v2 .uk-label-success, html.v2 .dw-tag-good { background: var(--dw-good-soft); color: var(--dw-good-text); }
html.v2 .uk-label-warning, html.v2 .dw-tag-warn { background: var(--dw-warn-soft); color: var(--dw-warn-text); }
html.v2 .uk-label-danger,  html.v2 .dw-tag-bad  { background: var(--dw-bad-soft);  color: var(--dw-bad-text); }
html.v2 .dw-tag-info { background: var(--dw-info-soft); color: var(--dw-info-text); }
html.v2 .dw-tag-sleep { background: var(--dw-sleep-soft); color: var(--dw-sleep-text); }
html.v2 .dw-tag-accent { background: var(--dw-accent-soft); color: var(--dw-accent-2); }
html.v2[data-dw-theme="dark"] .dw-tag-accent { color: var(--dw-accent); }
html.v2 .dw-tag .dw-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

/* filter chips */
html.v2 .dw-chips { display: flex; flex-wrap: wrap; gap: 8px; }

/* The row the grouping toggle and the type chips share. The 20px matches what
   a .dw-panel leaves above it, so the row is evenly set between the panels and
   the cards it filters. */
html.v2 .dw-chipsbar {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 8px 14px;
    margin-bottom: 20px;
}
html.v2 .dw-chipsbar .dw-chips { flex: 1 1 auto; min-width: 0; }

/* Sits at the end of the row, past the type chips. Muted until it is on: it
   reveals cards rather than narrowing them, so it should not read as one of
   the filters beside it. */
html.v2 .dw-archivedtoggle {
    flex: none;
    margin-left: auto;
    background: none;
    border-style: dashed;
    color: var(--dw-muted);
}
html.v2 .dw-archivedtoggle:hover { background: var(--dw-surface); }
/* .is-on, not the .is-active the type chips use: an accent-filled pill here
   would read as "Archived is the selected filter", which it is not. */
html.v2 .dw-archivedtoggle.is-on {
    border-style: solid;
    border-color: var(--dw-accent);
    background: var(--dw-accent-soft);
    color: var(--dw-accent-text);
}
html.v2 .dw-archivedtoggle.is-on .mdi { opacity: 1; }
html.v2 .dw-archivedtoggle.is-on .dw-count { color: var(--dw-accent-text); border-color: var(--dw-accent); }
/* On a narrow screen the row has already wrapped, so the auto margin would
   just push it off on its own line. */
@media (max-width: 640px) {
    html.v2 .dw-archivedtoggle { margin-left: 0; }
}

/* Styled as a chip so it reads as part of the same row, but it is a checkbox:
   it narrows nothing, it only changes how the results are laid out. */
html.v2 .dw-groupby {
    box-sizing: border-box;
    display: inline-flex; align-items: center; gap: 8px;
    flex: none;
    height: 36px; padding: 0 13px;
    border-radius: 999px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    color: var(--dw-text-2);
    font-size: 13.5px; font-weight: 500;
    white-space: nowrap; cursor: pointer;
    transition: background .16s, border-color .16s, color .16s;
}
html.v2 .dw-groupby:hover { border-color: var(--dw-border-strong); color: var(--dw-text); }
html.v2 .dw-groupby input { margin: 0 !important; flex: none; }
html.v2 .dw-groupby .mdi { font-size: 16px; line-height: 1; opacity: .7; }
html.v2 .dw-groupby.is-on {
    background: var(--dw-accent-soft);
    border-color: var(--dw-accent);
    color: var(--dw-accent-text);
}
html.v2 .dw-groupby.is-on .mdi { opacity: 1; }

/* A group heading inside the card grid. Spanning every column forces the group
   onto its own rows, which is the whole point of the toggle. */
html.v2 .dw-groupline {
    grid-column: 1 / -1;
    display: flex; align-items: center; gap: 10px;
    min-width: 0;
    /* A little more air above than below: the heading belongs to the cards
       that follow it, and the grid's own 20px gap sits under it. */
    margin: 10px 0 0;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--dw-border);
}
html.v2 .dw-groupline:first-child { margin-top: 0; }
html.v2 .dw-groupline-title {
    font-size: 12px; font-weight: 700;
    letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-text-2);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html.v2 .dw-groupline-count {
    flex: none;
    font-size: 11px; font-weight: 650;
    padding: 1px 7px; border-radius: 999px;
    background: var(--dw-surface-2); color: var(--dw-muted);
    border: 1px solid var(--dw-border);
}
html.v2 .dw-chip {
    display: inline-flex; align-items: center; gap: 8px;
    height: 36px; padding: 0 13px;
    border-radius: 999px; cursor: pointer;
    background: var(--dw-surface); border: 1px solid var(--dw-border);
    color: var(--dw-text-2); font-size: 13.5px; font-weight: 500;
    transition: background .16s, border-color .16s, color .16s, box-shadow .16s;
}
html.v2 .dw-chip:hover { border-color: var(--dw-border-strong); color: var(--dw-text); }
html.v2 .dw-chip .dw-ico { width: 15px; height: 15px; opacity: .65; }
html.v2 .dw-chip .mdi { font-size: 16px; opacity: .7; }
html.v2 .dw-chip .dw-count {
    font-size: 11.5px; font-weight: 650; padding: 1px 7px; border-radius: 999px;
    background: var(--dw-surface-2); color: var(--dw-muted); border: 1px solid var(--dw-border);
}
html.v2 .dw-chip.is-active {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent);
    box-shadow: 0 8px 20px -10px rgba(240, 160, 30, .95);
}
html.v2 .dw-chip.is-active .dw-ico,
html.v2 .dw-chip.is-active .mdi { opacity: 1; }
html.v2 .dw-chip.is-active .dw-count { background: rgba(0, 0, 0, .14); border-color: transparent; color: var(--dw-on-accent); }

/* glass pill used over imagery */
html.v2 .dw-pill {
    display: inline-flex; align-items: center; gap: 6px;
    height: 26px; padding: 0 9px; border-radius: 999px;
    font-size: 11.5px; font-weight: 600;
    color: #fff; background: rgba(10, 13, 18, .52);
    -webkit-backdrop-filter: blur(9px) saturate(150%);
    backdrop-filter: blur(9px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, .16);
    white-space: nowrap;
}
html.v2 .dw-pill .dw-ico { width: 13px; height: 13px; }
html.v2 .dw-pill .mdi { font-size: 14px; line-height: 1; }
html.v2 .dw-live-dot {
    width: 7px; height: 7px; border-radius: 50%; background: #35d68c;
    animation: dwPulse 2.2s ease-out infinite;
}
@keyframes dwPulse {
    0%   { box-shadow: 0 0 0 0 rgba(53, 214, 140, .6); }
    70%  { box-shadow: 0 0 0 7px rgba(53, 214, 140, 0); }
    100% { box-shadow: 0 0 0 0 rgba(53, 214, 140, 0); }
}

/* battery gauge */
html.v2 .dw-batt-shell {
    position: relative; display: inline-block;
    width: 21px; height: 11px; margin-right: 3px;
    border: 1.5px solid currentColor; border-radius: 3px; opacity: .95;
}
html.v2 .dw-batt-shell::after {
    content: ''; position: absolute; right: -4px; top: 2.5px;
    width: 2px; height: 5px; background: currentColor; border-radius: 0 1px 1px 0;
}
html.v2 .dw-batt-fill { display: block; height: 100%; width: 0; border-radius: 1px; background: currentColor; transition: width .6s ease; }
html.v2 .dw-batt.is-good { color: #8ff0b8; }
html.v2 .dw-batt.is-warn { color: #ffd479; }
html.v2 .dw-batt.is-bad  { color: #ffa3a3; }
html.v2 .dw-batt.is-unknown .dw-batt-shell,
html.v2 .dw-batt.is-loading .dw-batt-shell { opacity: .42; }

/* --------------------------------------------------------------------------
   12. Project / media grid
   -------------------------------------------------------------------------- */
html.v2 .dw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 20px; }
html.v2 .dw-grid-sm { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px; }

html.v2 .dw-tile {
    position: relative; display: flex; flex-direction: column;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    overflow: hidden;
    box-shadow: var(--dw-shadow-1);
    transition: transform .28s cubic-bezier(.2, .7, .3, 1), box-shadow .28s ease, border-color .28s ease;
    color: inherit;
}
html.v2 .dw-tile:hover { transform: translateY(-4px); box-shadow: var(--dw-shadow-2); border-color: var(--dw-border-strong); }
html.v2 .dw-tile:focus-visible { outline: 2px solid var(--dw-accent); outline-offset: 3px; }

html.v2 .dw-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--dw-surface-2); }
html.v2 .dw-media img {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    object-fit: cover; display: block;
    transition: transform .65s cubic-bezier(.2, .7, .3, 1), filter .3s ease;
}
html.v2 .dw-tile:hover .dw-media img { transform: scale(1.06); }
html.v2 .dw-media::after {
    content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none;
    background: linear-gradient(180deg, rgba(6, 9, 14, .34) 0%, rgba(6, 9, 14, 0) 34%, rgba(6, 9, 14, 0) 66%, rgba(6, 9, 14, .22) 100%);
}
html.v2 .dw-media-blank {
    position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    display: none; place-items: center;
    color: var(--dw-muted);
    background:
        repeating-linear-gradient(45deg, rgba(120, 132, 154, .07) 0 8px, transparent 8px 16px),
        var(--dw-surface-2);
}
html.v2 .dw-media.is-blank img { display: none; }
html.v2 .dw-media.is-blank .dw-media-blank { display: grid; }
html.v2 .dw-media-blank .mdi { font-size: 26px; opacity: .55; }

html.v2 .dw-badges {
    position: absolute; z-index: 2; top: 10px; left: 10px; right: 10px;
    display: flex; align-items: flex-start; gap: 6px; flex-wrap: wrap;
}
html.v2 .dw-badges-right { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

html.v2 .dw-media-note {
    position: absolute; z-index: 2; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    padding: 8px 15px; border-radius: 999px;
    font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: #fff; background: rgba(10, 13, 18, .58);
    border: 1px solid rgba(255, 255, 255, .2);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    max-width: calc(100% - 24px); text-align: center; line-height: 1.35;
}
html.v2 .dw-tile.is-muted .dw-media img { filter: blur(4px) grayscale(.5); transform: scale(1.09); }
html.v2 .dw-tile.is-muted:hover .dw-media img { transform: scale(1.12); }

html.v2 .dw-tile-body { display: flex; align-items: center; gap: 12px; padding: 13px 15px 15px; }
html.v2 .dw-tile-main { flex: 1; min-width: 0; }
html.v2 .dw-tile-name {
    margin: 0; font-size: 15.5px; font-weight: 600; letter-spacing: -.012em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-tile-meta {
    display: flex; align-items: center; gap: 6px; margin-top: 4px;
    font-size: 12.5px; color: var(--dw-muted); min-width: 0;
}
html.v2 .dw-tile-meta .dw-ico { width: 13px; height: 13px; }
html.v2 .dw-tile-meta .mdi { font-size: 14px; line-height: 1; }
html.v2 .dw-tile-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.v2 .dw-tile-meta.is-wrap,
html.v2 .dw-tile-meta.is-wrap span { white-space: normal; overflow: visible; text-overflow: clip; }
html.v2 .dw-tile-nav { padding: 20px; flex-direction: row; align-items: flex-start; gap: 14px; }
html.v2 .dw-tile-go {
    width: 32px; height: 32px; border-radius: 50%; flex: none;
    display: grid; place-items: center;
    background: var(--dw-surface-2); border: 1px solid var(--dw-border);
    color: var(--dw-text-2);
    transition: background .2s, border-color .2s, color .2s, transform .2s;
}
html.v2 .dw-tile-go .dw-ico { width: 15px; height: 15px; }
html.v2 .dw-tile:hover .dw-tile-go {
    background: var(--dw-accent); border-color: var(--dw-accent);
    color: var(--dw-on-accent); transform: translateX(2px);
}

/* --------------------------------------------------------------------------
   13. Gallery viewer bits (Vue components)
   -------------------------------------------------------------------------- */
html.v2 .uk-thumbnav { gap: 8px; margin: 0; padding: 4px 0; }
html.v2 .uk-thumbnav > * { padding-left: 0; }
html.v2 .uk-thumbnav > * > a,
html.v2 .uk-thumbnav img {
    border-radius: var(--dw-r-sm);
    overflow: hidden;
    border: 2px solid transparent;
    transition: border-color .16s, opacity .16s, transform .16s;
    display: block;
}
html.v2 .uk-thumbnav img { opacity: .72; }
html.v2 .uk-thumbnav img:hover { opacity: 1; transform: translateY(-2px); }
html.v2 .uk-thumbnav > .uk-active img,
html.v2 .uk-thumbnav > li.uk-active img { opacity: 1; border-color: var(--dw-accent); }

html.v2 .uk-slidenav {
    color: #fff;
    background: none;
    border: 0;
    box-sizing: border-box;
    width: 44px; height: 44px;
    display: grid; place-items: center;
    padding: 0;
    /* No pill behind the arrow, so it needs its own contrast against a
       bright frame. */
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .65));
    transition: none;
}
/* Never set `transform` here. UIkit centres these with
   [class*=uk-position-center-right]{top:50%;transform:translateY(-50%)}, so any
   transform of our own — even `none` — drops the arrow half its height down the
   frame the moment the rule applies. */
html.v2 .uk-slidenav:hover,
html.v2 .uk-slidenav:focus,
html.v2 .uk-slidenav:active { background: none; color: #fff; }
html.v2 .uk-slidenav-large { width: 52px; height: 52px; }
html.v2 .uk-position-center-left { left: 16px; }
html.v2 .uk-position-center-right { right: 16px; }

html.v2 .uk-overlay { background: rgba(10, 13, 18, .55); border-radius: var(--dw-r); }
html.v2 .uk-overlay-default { background: rgba(255, 255, 255, .88); color: var(--dw-text); }
html.v2[data-dw-theme="dark"] .uk-overlay-default { background: rgba(20, 24, 31, .9); color: var(--dw-text); }

html.v2 .uk-spinner, html.v2 .uk-icon { color: inherit; }
html.v2 .uk-progress {
    height: 8px; border-radius: 999px;
    background: var(--dw-surface-3);
    border: 0;
}
html.v2 .uk-progress::-webkit-progress-bar { background: var(--dw-surface-3); border-radius: 999px; }
html.v2 .uk-progress::-webkit-progress-value { background: var(--dw-accent); border-radius: 999px; }
html.v2 .uk-progress::-moz-progress-bar { background: var(--dw-accent); border-radius: 999px; }

html.v2 .dw-bar { height: 8px; border-radius: 999px; background: var(--dw-surface-3); overflow: hidden; }
html.v2 .dw-bar > span { display: block; height: 100%; background: var(--dw-accent); border-radius: 999px; transition: width .4s ease; }

/* tabs / subnav */
html.v2 .uk-tab { border-bottom: 1px solid var(--dw-border); margin: 0 0 20px; gap: 2px; }
html.v2 .uk-tab > * { padding-left: 0; }
html.v2 .uk-tab > * > a {
    padding: 10px 14px;
    border-bottom: 2px solid transparent;
    color: var(--dw-muted);
    font-size: 13.5px; font-weight: 600;
    text-transform: none;
}
html.v2 .uk-tab > * > a:hover { color: var(--dw-text); border-bottom-color: var(--dw-border-strong); }
html.v2 .uk-tab > .uk-active > a { color: var(--dw-accent-2); border-bottom-color: var(--dw-accent); }
html.v2[data-dw-theme="dark"] .uk-tab > .uk-active > a { color: var(--dw-accent); }

html.v2 .uk-subnav { gap: 6px; margin: 0 0 16px; }
html.v2 .uk-subnav > * { padding-left: 0; }
html.v2 .uk-subnav-pill > * > :first-child {
    padding: 7px 13px; border-radius: 999px;
    background: var(--dw-surface); border: 1px solid var(--dw-border);
    color: var(--dw-text-2); font-size: 13px; font-weight: 600; text-transform: none;
}
html.v2 .uk-subnav-pill > .uk-active > a { background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent); }

/* accordion */
html.v2 .uk-accordion { margin: 0; }
html.v2 .uk-accordion > * { margin-top: 8px; }
html.v2 .uk-accordion-title {
    padding: 13px 16px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    font-size: 14px; font-weight: 600; color: var(--dw-text);
}
html.v2 .uk-accordion-title::before { width: 15px; height: 15px; }
html.v2 .uk-accordion-content { margin-top: 10px; padding: 0 16px; font-size: 13.5px; color: var(--dw-text-2); }

/* --------------------------------------------------------------------------
   14. Date pickers (flatpickr / vue-flatpickr) & calendars
   -------------------------------------------------------------------------- */
html.v2 .flatpickr-calendar {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    box-shadow: var(--dw-shadow-2);
    font-family: var(--dw-font);
    color: var(--dw-text);
}
html.v2 .flatpickr-calendar.arrowTop::before,
html.v2 .flatpickr-calendar.arrowTop::after { border-bottom-color: var(--dw-surface); }
/* plugins.css paints the header bar #424242 — the Scutum picker's look, which
   inside the v2 calendar reads as a dark slab bolted onto a light panel. The
   month row belongs to the same surface as the days below it. */
html.v2 .flatpickr-months {
    background: transparent;
    margin-bottom: 0;
    padding-top: 4px;
    border-radius: var(--dw-r) var(--dw-r) 0 0;
}
html.v2 .flatpickr-months .flatpickr-month,
html.v2 .flatpickr-current-month,
html.v2 .flatpickr-monthDropdown-months { background: transparent; color: var(--dw-text); fill: var(--dw-text); }
html.v2 .flatpickr-current-month span.cur-month,
html.v2 .flatpickr-current-month input.cur-year { color: var(--dw-text); font-weight: 600; }
html.v2 .flatpickr-current-month .numInputWrapper:hover { background: var(--dw-surface-2); }
html.v2 .flatpickr-months .flatpickr-prev-month,
html.v2 .flatpickr-months .flatpickr-next-month { fill: var(--dw-text-2); }
/* plugins.css dims these to .6 so they read against its dark bar; on the light
   surface that is just faint. */
html.v2 .flatpickr-months .flatpickr-prev-month svg,
html.v2 .flatpickr-months .flatpickr-next-month svg { opacity: 1; }
html.v2 .flatpickr-months .flatpickr-prev-month:hover svg,
html.v2 .flatpickr-months .flatpickr-next-month:hover svg { fill: var(--dw-accent-2); }
html.v2 span.flatpickr-weekday { color: var(--dw-muted); font-weight: 700; font-size: 11px; text-transform: uppercase; }
html.v2 .flatpickr-day {
    color: var(--dw-text-2);
    border-radius: 9px;
    border-color: transparent;
}
html.v2 .flatpickr-day:hover { background: var(--dw-surface-2); border-color: transparent; color: var(--dw-text); }
html.v2 .flatpickr-day.today { border-color: var(--dw-accent); color: var(--dw-accent-2); font-weight: 700; }
html.v2 .flatpickr-day.selected,
html.v2 .flatpickr-day.startRange,
html.v2 .flatpickr-day.endRange,
html.v2 .flatpickr-day.selected:hover {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent); font-weight: 700;
}
html.v2 .flatpickr-day.inRange { background: var(--dw-accent-soft); border-color: transparent; box-shadow: none; }
html.v2 .flatpickr-day.flatpickr-disabled,
html.v2 .flatpickr-day.prevMonthDay,
html.v2 .flatpickr-day.nextMonthDay { color: var(--dw-muted); opacity: .45; }
html.v2 .flatpickr-time input,
html.v2 .flatpickr-time .flatpickr-am-pm { color: var(--dw-text); }

/* vue-monthly-picker + generic calendar grids */
html.v2 .month-picker-wrapper .picker,
html.v2 .month-picker-wrapper .month-picker {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    box-shadow: var(--dw-shadow-2);
}

/* --------------------------------------------------------------------------
   15. Empty states, skeletons, dividers
   -------------------------------------------------------------------------- */
html.v2 .dw-empty {
    text-align: center;
    padding: clamp(40px, 7vw, 76px) 24px;
    border: 1px dashed var(--dw-border-strong);
    border-radius: var(--dw-r-xl);
    background: var(--dw-surface);
    color: var(--dw-muted);
}
html.v2 .dw-empty .dw-ico { width: 38px; height: 38px; opacity: .5; }
html.v2 .dw-empty .mdi { font-size: 38px; opacity: .4; line-height: 1; }
html.v2 .dw-empty h2 { margin: 14px 0 6px; font-size: 17px; font-weight: 600; color: var(--dw-text); }
html.v2 .dw-empty p { margin: 0 auto; max-width: 44ch; font-size: 13.5px; }
html.v2 .dw-empty .uk-button,
html.v2 .dw-empty .dw-btn { margin-top: 18px; }

html.v2 .dw-skeleton {
    background: linear-gradient(90deg, var(--dw-surface-2) 25%, var(--dw-surface-3) 37%, var(--dw-surface-2) 63%);
    background-size: 400% 100%;
    animation: dwShimmer 1.4s ease infinite;
    border-radius: var(--dw-r-sm);
}
@keyframes dwShimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

html.v2 .dw-divider { height: 1px; background: var(--dw-border); margin: 24px 0; border: 0; }

html.v2 .dw-kv { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: 8px 18px; font-size: 13.5px; }
html.v2 .dw-kv dt { color: var(--dw-muted); font-weight: 500; }
html.v2 .dw-kv dd { margin: 0; color: var(--dw-text); font-weight: 500; }

/* --------------------------------------------------------------------------
   16. Text & colour utilities (v2 flavour of the UIkit ones)
   -------------------------------------------------------------------------- */
html.v2 .uk-text-meta,
html.v2 .dw-meta { font-size: 12.5px; color: var(--dw-muted); line-height: 1.5; }
html.v2 .uk-text-muted { color: var(--dw-muted); }
html.v2 .uk-text-lead { font-size: 17px; color: var(--dw-text-2); font-weight: 400; }
html.v2 .uk-text-primary { color: var(--dw-accent-2); }
html.v2 .uk-text-success { color: var(--dw-good-text); }
html.v2 .uk-text-warning { color: var(--dw-warn-text); }
html.v2 .uk-text-secondary { color: var(--dw-text-2); }
html.v2 .uk-text-small { font-size: 12.5px; }
html.v2 .uk-text-large { font-size: 17px; }
html.v2 .uk-heading-line > :before,
html.v2 .uk-heading-line > :after { border-bottom-color: var(--dw-border); }
html.v2 .uk-hr, html.v2 hr { border-top-color: var(--dw-border); }

html.v2 .uk-background-default { background: var(--dw-surface); }
html.v2 .uk-background-muted { background: var(--dw-surface-2); }
html.v2 .uk-tile-default { background: var(--dw-surface); }
html.v2 .uk-tile-muted { background: var(--dw-surface-2); }
html.v2 .uk-section-muted { background: var(--dw-surface-2); }
html.v2 .uk-placeholder {
    background: var(--dw-surface-2);
    border: 1px dashed var(--dw-border-strong);
    border-radius: var(--dw-r);
    color: var(--dw-muted);
}
html.v2 .uk-comment { background: var(--dw-surface); border-radius: var(--dw-r); }
html.v2 .uk-article-meta { color: var(--dw-muted); }
html.v2 .uk-description-list > dt { color: var(--dw-text); }

/* mdi icon sizing inside the redesign */
html.v2 .mdi { line-height: inherit; }
html.v2 .dw-content .mdi::before { font-size: inherit; }

/* --------------------------------------------------------------------------
   17. Auth / standalone pages
   -------------------------------------------------------------------------- */
html.v2 .dw-auth {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1fr;
    background: var(--dw-bg);
}
@media (min-width: 900px) {
    html.v2 .dw-auth { grid-template-columns: 1.05fr .95fr; }
}
html.v2 .dw-auth-aside {
    position: relative;
    display: none;
    padding: 48px;
    color: #fff;
    background: #0b0d11;
    overflow: hidden;
}
@media (min-width: 900px) {
    html.v2 .dw-auth-aside { display: flex; flex-direction: column; justify-content: space-between; }
}
html.v2 .dw-auth-aside img.dw-auth-shot {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    object-fit: cover; opacity: .5;
}
html.v2 .dw-auth-aside::after {
    content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(155deg, rgba(11, 13, 17, .78) 0%, rgba(11, 13, 17, .62) 35%, rgba(11, 13, 17, .94) 100%);
}
html.v2 .dw-auth-aside > * { position: relative; z-index: 2; }
html.v2 .dw-auth-aside h2 { color: #fff; font-size: clamp(24px, 3vw, 34px); letter-spacing: -.025em; margin: 0 0 12px; }
html.v2 .dw-auth-aside p { color: rgba(255, 255, 255, .72); font-size: 15px; max-width: 42ch; }
html.v2 .dw-auth-aside .dw-auth-logo img { height: 32px; }

html.v2 .dw-auth-main {
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    padding: clamp(28px, 6vw, 64px) clamp(20px, 5vw, 56px);
    background: var(--dw-surface);
}
html.v2 .dw-auth-card { width: 100%; max-width: 400px; }
html.v2 .dw-auth-card .dw-auth-brand { margin-bottom: 28px; }
html.v2 .dw-auth-card .dw-auth-brand img { height: 34px; }
html.v2 .dw-auth-card h1 { font-size: 25px; margin: 0 0 6px; letter-spacing: -.025em; }
html.v2 .dw-auth-card .dw-auth-lead { color: var(--dw-muted); font-size: 14px; margin: 0 0 26px; }
html.v2 .dw-auth-card .uk-button-primary { width: 100%; height: 44px; font-size: 14.5px; }
html.v2 .dw-auth-foot { margin-top: 24px; font-size: 13px; color: var(--dw-muted); text-align: center; }

/* ForgotPasswordComponent is shared with the classic sign-in page and carries
   its own "Back to login form" link, which toggles the .sc-toggle-* classes
   only that page has — so on v2 it does nothing. The card supplies its own
   "Back to sign in" instead. */
html.v2 .dw-auth a[data-uk-toggle*="sc-toggle-login-password"],
html.v2 .dw-signin a[data-uk-toggle*="sc-toggle-login-password"] { display: none; }
html.v2[data-dw-theme="dark"] .dw-auth-main { background: var(--dw-surface); }

/* --- sign-in page -------------------------------------------------------
   The classic /login layout, rebuilt on the v2 tokens: a single rotated sheet
   of three photo bands under a white column on the right. Element order and
   positioning mirror the classic page exactly — the art is the only
   positioned block, so it paints over the two static columns beside it, and
   the panel takes a z-index to come back over the top. */
html.v2 .dw-signin {
    position: relative;
    display: flex;
    min-height: 100vh;
    overflow: hidden;
    background: var(--dw-surface);
}
html.v2 .dw-signin-art {
    position: absolute;
    width: 120%; height: 150%;
    left: -25%; top: -25%;
    transform: rotate(-17deg);
    overflow: hidden;
}
html.v2 .dw-signin-band {
    position: relative;
    height: 33%;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
}
html.v2 .dw-signin-shot {
    position: absolute;
    display: block;
    width: 100%; height: 210%;
    transform: rotate(17deg);
    background-size: cover;
    background-repeat: no-repeat;
    filter: brightness(25%);
}
/* The captions are a 1:1 copy of the classic page's .image-text, down to the
   type. That means opting out of the v2 stack: app.css sets
   body{font-family:Roboto,Arial,Helvetica,sans-serif} and its own h1 rule, and
   the classic page inherits both. The <b> in particular is the classic <h1>,
   which picks up font-weight:300 from `.uk-h1,h1` — the parent's bold does not
   reach it — so leaving <b> at its default weight rendered it far heavier than
   the original. */
html.v2 .dw-signin-caption {
    /* Absolute, 100% x 210%, is what the classic caption actually computes to.
       Its own rule says position:relative, but `.image-row div` — written for
       the photo layer — also matches the caption and outranks it, so the real
       box is 1920x845 pinned at top:47%/left:-15% of the band, with the text
       centred inside that full-width box. As a relatively-positioned,
       shrink-to-fit flex item the same offsets land somewhere else entirely. */
    position: absolute;
    width: 100%;
    height: 210%;
    z-index: 1;
    display: block;
    padding: 20px;
    transform: rotate(17deg);
    text-align: center;
    color: #fff;
    font-family: Roboto, Arial, Helvetica, sans-serif;
    font-size: 24px;
    font-weight: bold;
    line-height: 1.5;
    text-shadow: 1px 1px 3px rgba(0, 0, 0, .7);
}
/* = .image-text h1 */
html.v2 .dw-signin-caption b {
    display: block;
    margin: 0;
    font-size: 4em;
    font-weight: 300;
    line-height: 1.2;
    letter-spacing: normal;
    color: #f9c62f;
    text-shadow: none;
}
/* = .image-text p */
html.v2 .dw-signin-caption i {
    display: block;
    margin: 0 0 20px;
    font-style: normal;
    color: #fff;
    text-shadow: none;
}
@media (max-width: 1600px) { html.v2 .dw-signin-caption b { font-size: 3em; } }
@media (max-width: 1350px) { html.v2 .dw-signin-caption b { font-size: 2em; } }

html.v2 .dw-signin-spacer { width: 60%; }
html.v2 .dw-signin-wedge { width: 10%; background: var(--dw-surface); }
html.v2 .dw-signin-wedge span { display: block; width: 100%; background: var(--dw-surface); }
html.v2 .dw-signin-wedge-top {
    height: 30vh; margin-bottom: -1px;
    clip-path: polygon(70% 0%, 0% 100%, 100% 100%, 100% 0%);
}
html.v2 .dw-signin-wedge-bottom {
    height: 70vh;
    clip-path: polygon(0% 0%, 0% 0%, 100% 100%, 100% 0%);
}

html.v2 .dw-signin-panel {
    position: relative;
    z-index: 2;
    /* The 30% is the column width the classic page uses; without border-box the
       40px padding would push the three columns past 100% and shrink them. */
    box-sizing: border-box;
    width: 30%;
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    padding: 40px 20px;
    background: var(--dw-surface);
}
html.v2 .dw-signin-card { width: 100%; max-width: 360px; }
html.v2 .dw-signin-logo { margin-bottom: 34px; text-align: center; }
html.v2 .dw-signin-logo img { max-width: 100%; height: auto; }
/* The regular logo's lettering is dark; the white one is for the dark panel. */
html.v2[data-dw-theme="dark"] .dw-signin-logo-light { display: none; }
html.v2:not([data-dw-theme="dark"]) .dw-signin-logo-dark { display: none; }
html.v2 .dw-signin-card .uk-button-primary { width: 100%; height: 44px; font-size: 14.5px; }

/* ForgotPasswordComponent is the classic page's markup, so its button is a
   Scutum .sc-button. Give it the v2 primary button; app.css marks the type
   scale !important, so those three declarations have to match it. */
html.v2 .dw-signin .sc-button {
    box-sizing: border-box;
    display: flex; align-items: center; justify-content: center;
    width: 100%; height: 44px; min-width: 0; padding: 0 18px; margin: 0;
    border: 1px solid var(--dw-accent); border-radius: var(--dw-r-sm);
    background: var(--dw-accent); color: var(--dw-on-accent);
    box-shadow: none; text-transform: none;
    font-family: var(--dw-font);
    font-size: 14.5px !important; font-weight: 600 !important; line-height: 1 !important;
    transition: background .16s, border-color .16s;
}
html.v2 .dw-signin .sc-button:hover,
html.v2 .dw-signin .sc-button:focus,
html.v2 .dw-signin .sc-button:active {
    background: var(--dw-accent-2); border-color: var(--dw-accent-2);
    color: #fff; box-shadow: none;
}
html.v2 .dw-signin .sc-login-page-inner label {
    display: block; margin-bottom: 6px;
    font-size: 12.5px; font-weight: 600; color: var(--dw-text-2);
}

@media (max-width: 768px) {
    html.v2 .dw-signin-art,
    html.v2 .dw-signin-spacer,
    html.v2 .dw-signin-wedge { display: none; }
    html.v2 .dw-signin-panel { width: 100%; }
}

/* error pages */
html.v2 .dw-error-page {
    min-height: 100vh;
    display: grid; place-items: center;
    padding: 40px 24px;
    text-align: center;
}
html.v2 .dw-error-code {
    font-size: clamp(64px, 16vw, 132px);
    font-weight: 700; line-height: .9;
    letter-spacing: -.05em;
    background: linear-gradient(140deg, var(--dw-accent), var(--dw-accent-2));
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
    margin: 0 0 8px;
}

/* --------------------------------------------------------------------------
   17b. TV mode overlay
   -------------------------------------------------------------------------- */
html.v2 .dw-tv { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 200; background: #000; display: none; }
html.v2 .dw-tv.is-on { display: block; }
html.v2 .dw-tv-slides { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
html.v2 .dw-tv-slide { position: absolute; top: 0; right: 0; bottom: 0; left: 0; opacity: 0; transition: opacity 1.1s ease; }
html.v2 .dw-tv-slide.is-active { opacity: 1; }
html.v2 .dw-tv-slide img { width: 100%; height: 100%; object-fit: contain; display: block; }
html.v2 .dw-tv-bar {
    position: absolute; left: 0; right: 0; bottom: 0;
    min-height: 60px; padding: 10px clamp(14px, 2vw, 28px);
    display: flex; align-items: center; gap: 18px; color: #fff;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, .75));
}
html.v2 .dw-tv-bar img { height: clamp(20px, 2.4vh, 30px); width: auto; }
html.v2 .dw-tv-bar .dw-tv-client { max-height: clamp(26px, 4vh, 52px); height: auto; background: transparent; }
html.v2 .dw-tv-name { flex: 1; text-align: center; font-size: clamp(15px, 2.1vw, 30px); font-weight: 600; letter-spacing: -.01em; }
html.v2 .dw-tv-time { font-size: clamp(11px, 1.1vw, 17px); color: rgba(255, 255, 255, .82); white-space: nowrap; }
html.v2 .dw-tv-exit {
    position: absolute; top: 16px; right: 16px; z-index: 3;
    width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
    display: grid; place-items: center;
    background: rgba(0, 0, 0, .5); border: 1px solid rgba(255, 255, 255, .22); color: #fff;
    opacity: 0; transition: opacity .2s;
}
html.v2 .dw-tv:hover .dw-tv-exit,
html.v2 .dw-tv-exit:focus-visible { opacity: 1; }
html.v2 .dw-tv-loading {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    display: grid; place-items: center;
    color: rgba(255, 255, 255, .7); font-size: 14px; letter-spacing: .04em;
}

/* clear button inside a search field */
html.v2 .dw-search-clear {
    position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
    width: 28px; height: 28px; border: 0; border-radius: 50%;
    background: transparent; color: var(--dw-muted);
    display: none; align-items: center; justify-content: center; cursor: pointer;
    padding: 0;
}
html.v2 .dw-search.has-value .dw-search-clear { display: flex; }
html.v2 .dw-search-clear:hover { background: var(--dw-surface-3); color: var(--dw-text); }

/* search field sitting in the dark top bar */
html.v2 .dw-topbar .dw-search { flex: 1 1 300px; max-width: 340px; min-width: 0; }
html.v2 .dw-topbar .dw-search input {
    box-sizing: border-box;
    width: 100%; height: 40px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .13);
    background: rgba(255, 255, 255, .06);
    color: var(--dw-rail-text);
    padding: 0 36px;
    font-size: 13.5px; outline: none;
    transition: border-color .18s, background .18s, box-shadow .18s;
}
html.v2 .dw-topbar .dw-search input::placeholder { color: var(--dw-rail-muted); }
html.v2 .dw-topbar .dw-search input:focus {
    border-color: var(--dw-accent);
    background: rgba(255, 255, 255, .1);
    box-shadow: 0 0 0 3px var(--dw-accent-soft);
}
html.v2 .dw-topbar .dw-search > .dw-ico,
html.v2 .dw-topbar .dw-search > .mdi { color: var(--dw-rail-muted); }
html.v2 .dw-topbar .dw-search-clear { color: var(--dw-rail-muted); }
html.v2 .dw-topbar .dw-search-clear:hover { background: rgba(255, 255, 255, .1); color: #fff; }
html.v2 .dw-kbd {
    position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
    font-size: 11px; font-weight: 600; color: var(--dw-rail-muted);
    border: 1px solid rgba(255, 255, 255, .15); border-radius: 5px;
    padding: 1px 5px; pointer-events: none; background: transparent;
}
html.v2 .dw-search.has-value .dw-kbd { display: none; }

@media (max-width: 720px) {
    html.v2 .dw-topbar-inner { flex-wrap: wrap; padding-top: 10px; padding-bottom: 10px; gap: 8px; }
    html.v2 .dw-topbar .dw-search { order: 5; flex-basis: 100%; max-width: none; }
    html.v2 .dw-kbd { display: none; }
    html.v2 .dw-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }

    /* Keep the whole action row on one line: trim the account button rather
       than letting it wrap under the brand. */
    html.v2 .dw-user-btn { padding: 0 7px; height: 38px; }
    html.v2 .dw-user-btn img { max-width: 58px; height: 26px; }
    html.v2 .dw-user-btn .dw-ico { display: none; }
    html.v2 .dw-iconbtn { width: 34px; height: 34px; }
    html.v2 .dw-navbar-actions .uk-navbar-nav > li > a { width: 34px; height: 34px; }
    html.v2 .dw-brand img { height: 22px; }
}

/* --------------------------------------------------------------------------
   17c. Compatibility with classic page bodies
   --------------------------------------------------------------------
   A page with no v2 view of its own still renders inside the v2 shell. These
   rules keep the Scutum-era wrappers from fighting the new layout.
   -------------------------------------------------------------------------- */
html.v2 .dw-content > #sc-page-content,
html.v2 .dw-content #sc-page-content { padding: 0; overflow: visible; }

html.v2 .sc-fab,
html.v2 .sc-fab-small {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    width: auto; height: 38px; padding: 0 16px;
    border-radius: var(--dw-r-sm);
    background: var(--dw-accent); color: var(--dw-on-accent);
    box-shadow: 0 8px 20px -12px rgba(240, 160, 30, .9);
    font-size: 13.5px; font-weight: 600;
    line-height: 1;
}
html.v2 .sc-fab:hover { background: var(--dw-accent-2); color: #fff; }
html.v2 .sc-fab .mdi { font-size: 17px; margin: 0; }
html.v2 .sc-fab-success { background: var(--dw-good); color: #fff; box-shadow: none; }
html.v2 .sc-fab-success:hover { filter: brightness(.94); color: #fff; }

/* The classic markup puts the heading in a .uk-card-title block that sits
   outside .uk-card-body; give it card-header spacing instead of nothing. */
html.v2 .uk-card > .uk-card-title {
    padding: 16px 20px;
    border-bottom: 1px solid var(--dw-border);
    margin: 0;
}
html.v2 .uk-card > .uk-card-title h3,
html.v2 .uk-card > .uk-card-title h1 { margin: 0; font-size: 16px; font-weight: 650; }
html.v2 .uk-card > .uk-card-title p { margin: 4px 0 0; }

/* Scutum breadcrumb */
html.v2 .uk-breadcrumb { margin: 0 0 16px; font-size: 12.5px; }
html.v2 .uk-breadcrumb > * > * { color: var(--dw-muted); font-size: 12.5px; }
html.v2 .uk-breadcrumb > * > :hover { color: var(--dw-text-2); }
html.v2 .uk-breadcrumb > :last-child > * { color: var(--dw-text); font-weight: 600; }

/* --------------------------------------------------------------------------
   18. Print
   -------------------------------------------------------------------------- */
@media print {
    html.v2 .dw-topbar,
    html.v2 .dw-rail,
    html.v2 .dw-page-actions { display: none !important; }
    html.v2 .dw-content { padding: 0; }
    html.v2 .dw-card, html.v2 .uk-card, html.v2 .dw-table-wrap { box-shadow: none; border-color: #ccc; }
}

/* --------------------------------------------------------------------------
   18b. Hardening against !important rules in app.css
   --------------------------------------------------------------------
   The Scutum layer in app.css marks a handful of declarations !important, so
   normal specificity cannot beat them. These are the exact ones the redesign
   needs back — nothing more, so the rest of the cascade still behaves.
   -------------------------------------------------------------------------- */
html.v2 .uk-input,
html.v2 .uk-select,
html.v2 .uk-textarea {
    background-color: var(--dw-surface) !important;
    color: var(--dw-text) !important;
    border-color: var(--dw-border-strong) !important;
}
html.v2 .uk-input:focus,
html.v2 .uk-select:focus,
html.v2 .uk-textarea:focus { border-color: var(--dw-accent) !important; }
html.v2 .uk-input:disabled,
html.v2 .uk-select:disabled,
html.v2 .uk-textarea:disabled { background-color: var(--dw-surface-2) !important; color: var(--dw-muted) !important; }
html.v2 .uk-form-danger,
html.v2 .uk-input.uk-form-danger,
html.v2 .uk-select.uk-form-danger,
html.v2 .uk-textarea.uk-form-danger { border-color: var(--dw-bad) !important; color: var(--dw-text) !important; }
html.v2 .uk-form-success { border-color: var(--dw-good) !important; color: var(--dw-text) !important; }

html.v2 .uk-alert { background: var(--dw-surface) !important; color: var(--dw-text-2) !important; }
html.v2 .uk-alert-primary { background: var(--dw-info-soft) !important; color: var(--dw-text) !important; }
html.v2 .uk-alert-success { background: var(--dw-good-soft) !important; color: var(--dw-text) !important; }
html.v2 .uk-alert-warning { background: var(--dw-warn-soft) !important; color: var(--dw-text) !important; }
html.v2 .uk-alert-danger  { background: var(--dw-bad-soft)  !important; color: var(--dw-text) !important; }
html.v2 .uk-alert-close { margin: 0 !important; top: 12px; right: 12px; }

html.v2 .uk-button-default { border-color: var(--dw-border-strong) !important; }
html.v2 .uk-button-default:hover { border-color: var(--dw-muted) !important; }
html.v2 .uk-button-primary { border-color: var(--dw-accent) !important; }
html.v2 .uk-button-primary:hover { border-color: var(--dw-accent-2) !important; }
html.v2 .uk-button-danger { border-color: var(--dw-bad) !important; }

html.v2 .uk-card-header { padding: 16px 20px !important; }
html.v2 .uk-card-small .uk-card-body { padding: 16px !important; }
html.v2 .uk-card-large .uk-card-body { padding: 28px !important; }

html.v2 .uk-dropdown,
html.v2 .uk-navbar-dropdown { border: 1px solid var(--dw-border) !important; }

/* --------------------------------------------------------------------------
   19. Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html.v2 *,
    html.v2 *::before,
    html.v2 *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
}

/* --------------------------------------------------------------------------
   20. Portal v2 — overview, project cards, camera page
   --------------------------------------------------------------------------
   Everything the /projects and /camera/{id} pages add on top
   of the shared system. Same tokens, same dw- prefix, same html.v2 scope.
   -------------------------------------------------------------------------- */

/* --- topbar project picker --- */
html.v2 .dw-projsel { position: relative; flex: none; min-width: 0; }
html.v2 .dw-projsel-btn {
    display: flex; align-items: center; gap: 8px;
    height: 38px; padding: 0 10px 0 12px; max-width: 260px;
    border-radius: 11px; cursor: pointer;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .1);
    color: var(--dw-rail-text);
    font-size: 13.5px; font-weight: 550;
    transition: background .16s, border-color .16s;
}
html.v2 .dw-projsel-btn:hover { background: rgba(255, 255, 255, .11); }
html.v2 .dw-projsel-btn > .mdi { font-size: 18px; color: var(--dw-rail-muted); flex: none; }
html.v2 .dw-projsel-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.v2 .dw-projsel-caret { font-size: 17px; color: var(--dw-rail-muted); flex: none; transition: transform .18s; }
html.v2 .dw-projsel-btn[aria-expanded="true"] .dw-projsel-caret { transform: rotate(180deg); }

html.v2 .dw-projsel-menu {
    position: absolute; left: 0; top: calc(100% + 8px);
    width: min(340px, 88vw); padding: 6px;
    background: var(--dw-surface); color: var(--dw-text);
    border: 1px solid var(--dw-border);
    border-radius: 14px;
    box-shadow: var(--dw-shadow-2);
    opacity: 0; transform: translateY(-6px) scale(.98);
    pointer-events: none;
    transition: opacity .16s ease, transform .16s ease;
    z-index: 70;
}
html.v2 .dw-projsel-menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
html.v2 .dw-projsel-search { position: relative; padding: 4px 4px 8px; }
html.v2 .dw-projsel-search .mdi {
    position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
    font-size: 17px; color: var(--dw-muted); pointer-events: none;
}
html.v2 .dw-projsel-search input {
    box-sizing: border-box;
    width: 100%; height: 38px; padding: 0 12px 0 36px;
    border-radius: 10px; border: 1px solid var(--dw-border);
    background: var(--dw-surface-2); color: var(--dw-text);
    font-size: 13.5px; font-family: inherit;
    -webkit-appearance: none; appearance: none;
}
html.v2 .dw-projsel-search input:focus { outline: none; border-color: var(--dw-accent); background: var(--dw-surface); }
html.v2 .dw-projsel-search input::-webkit-search-cancel-button { display: none; }

html.v2 .dw-projsel-list { max-height: min(420px, 56vh); overflow-y: auto; }
html.v2 .dw-projsel-list a {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px; border-radius: 10px;
    color: var(--dw-text-2); font-size: 13.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-projsel-list a:hover { background: var(--dw-surface-2); color: var(--dw-text); }
html.v2 .dw-projsel-list a.is-current { background: var(--dw-accent-soft); color: var(--dw-accent-text); font-weight: 600; }
html.v2 .dw-projsel-list .mdi { font-size: 17px; opacity: .75; flex: none; }
html.v2 .dw-projsel-dot {
    width: 7px; height: 7px; border-radius: 50%; flex: none;
    background: var(--dw-border-strong);
}
html.v2 .dw-projsel-list a.is-current .dw-projsel-dot { background: currentColor; }
html.v2 .dw-projsel-all { border-bottom: 1px solid var(--dw-border); border-radius: 10px 10px 0 0; margin-bottom: 4px; }
html.v2 .dw-projsel-empty { padding: 14px 12px; font-size: 13px; color: var(--dw-muted); text-align: center; }

/* --- panels ------------------------------------------------------------- */
/* Every one of these is used as a grid or flex item somewhere, where the
   default min-width:auto means "never shrink below your widest unbreakable
   child" — one long nowrap label and the box bursts out of its column. On a
   plain block min-width already computes to 0, so this costs nothing. */
html.v2 .dw-panel,
html.v2 .dw-card,
html.v2 .dw-step,
html.v2 .dw-tile { min-width: 0; }

html.v2 .dw-panel {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    padding: 18px 20px;
    margin: 0 0 20px;
}
html.v2 .dw-panel-head {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px;
    margin: 0 0 14px;
}
html.v2 .dw-panel-title { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
html.v2 .dw-panel-note { font-size: 12px; color: var(--dw-muted); }
html.v2 .dw-panel-head .dw-panel-note:last-child { margin-left: auto; }
html.v2 .dw-panel-empty { margin: 0; padding: 10px 0; font-size: 13px; color: var(--dw-muted); }
html.v2 .dw-panel-foot { display: block; margin: 12px 0 0; padding-top: 12px; border-top: 1px solid var(--dw-border); }

html.v2 .dw-dotsep {
    display: inline-block; width: 3px; height: 3px; border-radius: 50%;
    background: currentColor; opacity: .5; vertical-align: middle; margin: 0 7px;
}

/* System overview and Camera health read as one unit, so they sit closer to
   each other than to the cards below. */
html.v2 .dw-overview { margin-bottom: 12px; }
html.v2 .dw-health { margin-bottom: 24px; }

/* Lists that run to the panel edge do not need the panel's bottom padding. */
html.v2 .dw-activity,
html.v2 .dw-daybars { padding-bottom: 14px; }
html.v2 .dw-shots { padding-bottom: 16px; }

/* --- system overview strip ---------------------------------------------- */
/* A single non-wrapping row that scrolls when it has to. An auto-fit grid
   would wrap, and the `+` divider below cannot tell a wrapped row from a
   continued one — it would draw a rule hanging in space at the row start. */
html.v2 .dw-statbar {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
}
/* These rows scroll rather than wrap, because the `+` divider below cannot
   tell a wrapped row from a continued one. The file's thin global scrollbar is
   left visible on them on purpose: it is the affordance that says there is
   more to the right, and unlike a mask it cannot dim a row that fits. */
html.v2 .dw-statbar,
html.v2 .dw-camstats { scroll-snap-type: x proximity; }
html.v2 .dw-statbar-item,
html.v2 .dw-camstat { scroll-snap-align: start; }
html.v2 .dw-statbar:focus-visible,
html.v2 .dw-camstats:focus-visible { outline: 2px solid var(--dw-accent); outline-offset: -2px; }
html.v2 .dw-statbar-item {
    display: flex; align-items: center; gap: 13px;
    padding: 6px 20px 6px 0;
    position: relative;
    flex: 1 0 auto;
    min-width: 0;
}
html.v2 .dw-statbar-item + .dw-statbar-item { padding-left: 20px; }
html.v2 .dw-statbar-item + .dw-statbar-item::before {
    content: ''; position: absolute; left: 0; top: 6px; bottom: 6px;
    width: 1px; background: var(--dw-border);
}
html.v2 .dw-statbar-ico {
    width: 40px; height: 40px; border-radius: var(--dw-r); flex: none;
    display: grid; place-items: center;
    background: var(--dw-surface-2);
    color: var(--dw-text-2);
}
html.v2 .dw-statbar-ico .mdi { font-size: 21px; line-height: 1; }
html.v2 .dw-statbar-ico.is-accent { background: var(--dw-accent-soft); color: var(--dw-accent-2); }
html.v2[data-dw-theme="dark"] .dw-statbar-ico.is-accent { color: var(--dw-accent); }
html.v2 .dw-statbar-ico.is-info { background: var(--dw-info-soft); color: var(--dw-info); }
html.v2 .dw-statbar-ico.is-good { background: var(--dw-good-soft); color: var(--dw-good); }
html.v2 .dw-statbar-ico.is-sleep { background: var(--dw-sleep-soft); color: var(--dw-sleep-text); }
html.v2 .dw-statbar-body { min-width: 0; display: flex; flex-direction: column; }
html.v2 .dw-statbar-value {
    font-size: clamp(19px, 2vw, 24px); font-weight: 650; letter-spacing: -.025em;
    line-height: 1.15; font-variant-numeric: tabular-nums;
}
html.v2 .dw-statbar-label { font-size: 12px; color: var(--dw-muted); margin-top: 2px; }

/* percentage ring */
html.v2 .dw-ring {
    width: 40px; height: 40px; flex: none; border-radius: 50%;
    display: grid; place-items: center;
    background: conic-gradient(currentColor calc(var(--dw-ring-pct, 0) * 1%), var(--dw-surface-3) 0);
    color: var(--dw-good);
    position: relative;
}
html.v2 .dw-ring::after {
    content: ''; position: absolute; inset: 4px; border-radius: 50%;
    background: var(--dw-surface);
}
html.v2 .dw-ring-dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; position: relative; z-index: 1; }
html.v2 .dw-ring.is-good { color: var(--dw-good); }
html.v2 .dw-ring.is-warn { color: var(--dw-warn); }
html.v2 .dw-ring.is-bad  { color: var(--dw-bad); }
html.v2 .dw-ring.is-sleep { color: var(--dw-sleep); }
html.v2 .dw-ring.is-mute { color: var(--dw-border-strong); }

/* --- camera health bar --------------------------------------------------- */
html.v2 .dw-healthbar {
    display: flex; gap: 4px; height: 12px; margin: 4px 0 14px;
}
html.v2 .dw-healthbar-seg { border-radius: 999px; min-width: 8px; transition: flex-grow .3s ease; }
html.v2 .dw-healthbar-seg.is-good { background: var(--dw-good); }
html.v2 .dw-healthbar-seg.is-warn { background: var(--dw-warn); }
html.v2 .dw-healthbar-seg.is-bad  { background: var(--dw-bad); }
html.v2 .dw-healthbar-seg.is-sleep { background: var(--dw-sleep); }
html.v2 .dw-healthbar-seg.is-mute { background: var(--dw-border-strong); }

html.v2 .dw-healthkeys {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px 16px;
}
html.v2 .dw-healthkey { display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; color: var(--dw-muted); }
html.v2 .dw-healthkey b { font-size: 17px; font-weight: 650; color: var(--dw-text); font-variant-numeric: tabular-nums; }
html.v2 .dw-healthkey-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; align-self: center; }
html.v2 .dw-healthkey.is-good .dw-healthkey-dot { background: var(--dw-good); }
html.v2 .dw-healthkey.is-warn .dw-healthkey-dot { background: var(--dw-warn); }
html.v2 .dw-healthkey.is-bad  .dw-healthkey-dot { background: var(--dw-bad); }
html.v2 .dw-healthkey.is-sleep .dw-healthkey-dot { background: var(--dw-sleep); }
html.v2 .dw-healthkey.is-mute .dw-healthkey-dot { background: var(--dw-border-strong); }

/* --- two column page layout --------------------------------------------- */
html.v2 .dw-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
html.v2 .dw-layout-main { min-width: 0; }
html.v2 .dw-layout-side { min-width: 0; }
/* The activity rail only earns its 320px once the cards still have room for a
   three-up grid beside it; below that it stacks under them. */
@media (min-width: 1400px) {
    html.v2 .dw-layout { grid-template-columns: minmax(0, 1fr) 320px; }
    html.v2 .dw-layout-side { position: sticky; top: calc(var(--dw-topbar-h) + 20px); }
}

/* --- project card -------------------------------------------------------- */
html.v2 .dw-projcard { overflow: visible; }
/* Wider than the shared .dw-grid default: these cards carry a three-column
   stat footer that needs the room. */
html.v2 .dw-layout-main .dw-grid { grid-template-columns: repeat(auto-fill, minmax(288px, 1fr)); }
html.v2 .dw-projcard:hover { transform: translateY(-3px); }
html.v2 .dw-projcard-media {
    display: block; position: relative;
    border-radius: var(--dw-r-lg) var(--dw-r-lg) 0 0;
    overflow: hidden;
    aspect-ratio: 16 / 9;
}
html.v2 .dw-projcard-type {
    position: absolute; left: 12px; bottom: 12px; z-index: 2;
    display: inline-flex; align-items: center; gap: 5px;
    height: 24px; padding: 0 9px; border-radius: 999px;
    font-size: 11px; font-weight: 600; color: #fff;
    background: rgba(10, 13, 18, .5);
    -webkit-backdrop-filter: blur(9px) saturate(150%);
    backdrop-filter: blur(9px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, .14);
    opacity: 0; transform: translateY(4px);
    transition: opacity .22s, transform .22s;
}
/* Touch devices never resolve :hover, and the badge is the only place a card
   states its feed type — so it is visible by default and only hidden where a
   real pointer can reveal it. */
html.v2 .dw-projcard-type { opacity: 1; transform: none; }
@media (hover: hover) and (pointer: fine) {
    html.v2 .dw-projcard-type { opacity: 0; transform: translateY(4px); }
    html.v2 .dw-projcard:hover .dw-projcard-type { opacity: 1; transform: none; }
}
html.v2 .dw-projcard-type .mdi { font-size: 13px; }
html.v2 .dw-pill.is-good { background: rgba(22, 140, 80, .78); border-color: rgba(255, 255, 255, .22); }
/* Sleep and New sit on the same glass as the rest of the badge row — tinted
   enough to read as a state, never loud enough to fight the thumbnail. */
html.v2 .dw-pill.is-sleep { background: rgba(52, 66, 89, .62); border-color: rgba(255, 255, 255, .2); }
html.v2 .dw-pill.is-new { background: rgba(202, 128, 12, .82); border-color: rgba(255, 255, 255, .24); color: #fff; }
html.v2 .dw-pill.is-warn { background: rgba(163, 109, 0, .8); border-color: rgba(255, 255, 255, .22); }
html.v2 .dw-pill.is-bad { background: rgba(176, 46, 46, .8); border-color: rgba(255, 255, 255, .22); }
html.v2 .dw-pill.is-mute { background: rgba(10, 13, 18, .58); }

/* "Next photo due 15m 10s" — replaces the health line on a live feed that is
   behaving, where the next frame is the only thing worth saying. */
html.v2 .dw-nextshot .mdi { font-size: 15px; line-height: 1; flex: none; }
html.v2 .dw-nextshot b { font-weight: 700; font-variant-numeric: tabular-nums; }
html.v2 .dw-nextshot.is-sleep,
html.v2 .dw-nextshot.is-good { color: var(--dw-text-2); }

html.v2 .dw-projcard-body { padding: 14px 16px 0; display: flex; flex-direction: column; flex: 1; }
html.v2 .dw-projcard-top { display: flex; align-items: flex-start; gap: 8px; }
html.v2 .dw-projcard .dw-tile-name { flex: 1; min-width: 0; margin: 0; font-size: 15.5px; font-weight: 650; letter-spacing: -.012em; }
html.v2 .dw-projcard .dw-tile-name a { color: var(--dw-text); }
html.v2 .dw-projcard .dw-tile-name a:hover { color: var(--dw-accent-text); }

html.v2 .dw-projcard-menu { position: relative; flex: none; }
html.v2 .dw-projcard-more { width: 30px; height: 30px; border-radius: 9px; color: var(--dw-muted); }
html.v2 .dw-projcard-more:hover { background: var(--dw-surface-2); border-color: var(--dw-border); color: var(--dw-text); }
html.v2 .dw-projcard-menu .dw-menu { top: calc(100% + 6px); min-width: 196px; }

html.v2 .dw-projcard-meta { margin: 5px 0 0; font-size: 12.5px; color: var(--dw-muted); }
html.v2 .dw-projcard-status {
    margin: 9px 0 0; font-size: 12.5px; font-weight: 600;
    display: flex; align-items: center; gap: 7px;
}
html.v2 .dw-projcard-status.is-good { color: var(--dw-good-text); }
html.v2 .dw-projcard-status.is-warn { color: var(--dw-warn-text); }
html.v2 .dw-projcard-status.is-bad  { color: var(--dw-bad-text); }
html.v2 .dw-projcard-status.is-sleep { color: var(--dw-sleep-text); }
html.v2 .dw-projcard-status.is-mute { color: var(--dw-muted); }
html.v2 .dw-statusdot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }

/* the stat footer */
html.v2 .dw-tilestats {
    display: grid;
    /* The date needs its natural width; the two counts share what is left. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, auto);
    /* auto top margin pins the footer to the card's bottom edge, so the
       footers of a row of cards line up whatever the titles do. */
    margin: auto -16px 0;
    padding: 12px 16px 14px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-tilestat { position: relative; min-width: 0; padding: 0 8px; text-align: center; }
html.v2 .dw-tilestat:first-child { padding-left: 0; text-align: left; }
html.v2 .dw-tilestat:last-child { padding-right: 0; text-align: right; }
html.v2 .dw-tilestat + .dw-tilestat::before {
    content: ''; position: absolute; left: 0; top: 2px; bottom: 2px;
    width: 1px; background: var(--dw-border);
}
/* Block, not flex: text-overflow has no effect on a flex container's
   anonymous text item, and the date is the one value that can outgrow its
   column. The icon rides along as inline content. */
html.v2 .dw-tilestat-value {
    display: block;
    font-size: 13px; font-weight: 650; color: var(--dw-text);
    letter-spacing: -.015em; font-variant-numeric: tabular-nums;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.v2 .dw-tilestat-value .mdi {
    font-size: 14px; color: var(--dw-muted);
    margin-right: 5px; vertical-align: -1px;
}
html.v2 .dw-tilestat-label {
    display: block; margin-top: 2px;
    font-size: 10.5px; letter-spacing: -.005em; color: var(--dw-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- activity list ------------------------------------------------------- */
html.v2 .dw-activity-day {
    font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--dw-muted);
    padding: 12px 0 6px;
}
html.v2 .dw-activity-day:first-of-type { padding-top: 0; }
html.v2 .dw-activity-list { list-style: none; margin: 0; padding: 0; }
html.v2 .dw-activity-list a {
    display: flex; align-items: center; gap: 10px;
    padding: 8px; margin: 0 -8px;
    border-radius: 10px;
    color: var(--dw-text);
}
html.v2 .dw-activity-list a:hover { background: var(--dw-surface-2); }
html.v2 .dw-activity-ico {
    width: 30px; height: 30px; border-radius: 9px; flex: none;
    display: grid; place-items: center;
    background: var(--dw-good-soft); color: var(--dw-good-text);
}
html.v2 .dw-activity-ico.is-warn { background: var(--dw-warn-soft); color: var(--dw-warn-text); }
html.v2 .dw-activity-ico.is-sleep { background: var(--dw-sleep-soft); color: var(--dw-sleep-text); }
html.v2 .dw-activity-ico .mdi { font-size: 16px; }
html.v2 .dw-activity-body { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
html.v2 .dw-activity-body b { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.v2 .dw-activity-body span { font-size: 11.5px; color: var(--dw-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.v2 .dw-activity-time { font-size: 11.5px; color: var(--dw-muted); flex: none; font-variant-numeric: tabular-nums; }

/* --- camera page --------------------------------------------------------- */
html.v2 .dw-camlayout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
@media (min-width: 1180px) {
    html.v2 .dw-camlayout { grid-template-columns: minmax(0, 1fr) 330px; }
}
html.v2 .dw-camlayout-main, html.v2 .dw-camlayout-side { min-width: 0; }

html.v2 .dw-title-tag { vertical-align: middle; margin-left: 10px; font-size: 11px; letter-spacing: .06em; }
html.v2 .dw-title-tag .dw-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

html.v2 .dw-camhero {
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    overflow: hidden;
    margin-bottom: 20px;
}
html.v2 .dw-camhero-frame {
    display: block; position: relative;
    aspect-ratio: 16 / 9;
    background: var(--dw-surface-2);
    overflow: hidden;
}
html.v2 .dw-camhero-frame img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; display: block;
}
/* Swap layers: the incoming frame is decoded underneath and then brought to the
   front, rather than replacing the src of the visible one — which shows the
   empty frame for however long the new image takes to arrive. The swap itself
   is a straight cut; no transition, so a slideshow does not fade every step. */
html.v2 .dw-camhero-frame .dw-camhero-img {
    opacity: 0;
    z-index: 0;
}
/* Stays under the stamp and the "Full size" pill, which are both z-index 2. */
html.v2 .dw-camhero-frame .dw-camhero-img.is-on { opacity: 1; z-index: 1; }
html.v2 .dw-camhero-frame.is-empty {
    display: grid; place-content: center; justify-items: center; gap: 8px;
    color: var(--dw-muted); text-align: center; padding: 24px;
}
html.v2 .dw-camhero-frame.is-empty .mdi { font-size: 40px; opacity: .5; }
html.v2 .dw-camhero-frame.is-empty p { margin: 0; font-size: 13.5px; }

html.v2 .dw-camhero-stamp {
    position: absolute; left: 14px; top: 14px; z-index: 2;
    display: flex; flex-direction: column; line-height: 1.25;
    padding: 8px 12px; border-radius: var(--dw-r-sm);
    background: rgba(10, 13, 18, .58);
    -webkit-backdrop-filter: blur(9px) saturate(150%);
    backdrop-filter: blur(9px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, .14);
    color: #fff;
}
html.v2 .dw-camhero-stamp b { font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; }
html.v2 .dw-camhero-stamp span { font-size: 11.5px; opacity: .8; }

html.v2 .dw-camhero-open {
    position: absolute; right: 14px; bottom: 14px; z-index: 2;
    display: inline-flex; align-items: center; gap: 6px;
    height: 30px; padding: 0 12px; border-radius: 999px;
    font-size: 12px; font-weight: 600; color: #fff;
    background: rgba(10, 13, 18, .52);
    -webkit-backdrop-filter: blur(9px) saturate(150%);
    backdrop-filter: blur(9px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, .16);
    opacity: 0; transform: translateY(4px);
    transition: opacity .2s, transform .2s;
}
html.v2 .dw-camhero-open { opacity: 1; transform: none; }
@media (hover: hover) and (pointer: fine) {
    html.v2 .dw-camhero-open { opacity: 0; transform: translateY(4px); }
    html.v2 .dw-camhero-frame:hover .dw-camhero-open { opacity: 1; transform: none; }
}

/* status chip row under the hero */
/* Same one-row rule as .dw-statbar — see the note there. */
html.v2 .dw-camstats {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding: 14px 18px;
    border-top: 1px solid var(--dw-border);
    background: var(--dw-surface-2);
}
html.v2 .dw-camstat {
    display: flex; align-items: center; gap: 11px;
    padding: 6px 16px 6px 0;
    position: relative;
    flex: 1 0 auto;
    min-width: 0;
}
html.v2 .dw-camstat + .dw-camstat { padding-left: 16px; }
html.v2 .dw-camstat + .dw-camstat::before {
    content: ''; position: absolute; left: 0; top: 6px; bottom: 6px; width: 1px; background: var(--dw-border);
}
html.v2 .dw-camstat-ico {
    width: 32px; height: 32px; border-radius: 10px; flex: none;
    display: grid; place-items: center;
    background: var(--dw-surface-3); color: var(--dw-text-2);
}
html.v2 .dw-camstat-ico .mdi { font-size: 17px; line-height: 1; }
html.v2 .dw-camstat-ico.is-good { background: var(--dw-good-soft); color: var(--dw-good-text); }
html.v2 .dw-camstat-ico.is-warn { background: var(--dw-warn-soft); color: var(--dw-warn-text); }
html.v2 .dw-camstat-ico.is-bad  { background: var(--dw-bad-soft);  color: var(--dw-bad-text); }
html.v2 .dw-camstat-ico.is-sleep { background: var(--dw-sleep-soft); color: var(--dw-sleep-text); }
html.v2 .dw-camstat-ico.is-info { background: var(--dw-info-soft); color: var(--dw-info); }
html.v2 .dw-camstat-ico.is-accent { background: var(--dw-accent-soft); color: var(--dw-accent-2); }
html.v2[data-dw-theme="dark"] .dw-camstat-ico.is-accent { color: var(--dw-accent); }
html.v2 .dw-camstat-body { min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
html.v2 .dw-camstat-body > b {
    font-size: 13.5px; font-weight: 650; color: var(--dw-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-variant-numeric: tabular-nums;
}
html.v2 .dw-camstat-body > span { font-size: 11.5px; color: var(--dw-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the battery gauge is dark-on-light here rather than over an image */
html.v2 .dw-camstat .dw-batt { display: inline-flex; align-items: center; gap: 2px; color: var(--dw-good-text); }
html.v2 .dw-camstat .dw-batt.is-warn { color: var(--dw-warn-text); }
html.v2 .dw-camstat .dw-batt.is-bad  { color: var(--dw-bad-text); }
html.v2 .dw-camstat .dw-batt.is-unknown,
html.v2 .dw-camstat .dw-batt.is-loading { color: var(--dw-muted); }

/* --- timeline scrubber --------------------------------------------------- */
html.v2 .dw-timeline { position: relative; }
html.v2 .dw-timeline.is-busy { opacity: .55; pointer-events: none; }
html.v2 .dw-timeline-sampled { color: var(--dw-accent-text); }

html.v2 .dw-timeline-body { padding: 4px 10px 0; }
html.v2 .dw-timeline-ticks { position: relative; height: 18px; margin-bottom: 4px; }
html.v2 .dw-timeline-tick {
    position: absolute; top: 0; transform: translateX(-50%);
    font-size: 10.5px; font-weight: 600; color: var(--dw-muted);
    white-space: nowrap; font-variant-numeric: tabular-nums;
}

html.v2 .dw-timeline-track {
    position: relative; height: 26px; cursor: pointer;
    border-radius: 999px;
}
html.v2 .dw-timeline-track:focus-visible { outline: 2px solid var(--dw-accent); outline-offset: 4px; }
html.v2 .dw-timeline-rail {
    position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
    height: 4px; border-radius: 999px; background: var(--dw-surface-3);
}
/* The overlay spans the whole track, so it has to stay out of hit testing or
   it would be the target of every click meant for the rail. */
html.v2 .dw-timeline-dots { position: absolute; inset: 0; pointer-events: none; }
html.v2 .dw-timeline-dot {
    position: absolute; top: 50%;
    /* Border-box, so .is-current's 4px ring counts inside its 15px box and the
       negative margin that centres it on the track stays correct. Without it
       the marker is really 23px wide and sits 4px below the rail. */
    box-sizing: border-box;
    width: 8px; height: 8px; margin: -4px 0 0 -4px;
    padding: 0; border: 0; border-radius: 50%; cursor: pointer;
    background: var(--dw-good);
    pointer-events: auto;
    transition: transform .14s ease;
}
html.v2 .dw-timeline-dot:hover { transform: scale(1.6); z-index: 3; }
html.v2 .dw-timeline-dot.is-current {
    width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
    background: var(--dw-surface);
    border: 4px solid var(--dw-good);
    box-shadow: 0 0 0 4px var(--dw-good-soft);
    z-index: 2;
}

html.v2 .dw-timeline-foot {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    margin-top: 16px; padding-top: 14px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-timeline-controls { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
html.v2 .dw-timeline-controls .dw-iconbtn {
    width: 34px; height: 34px; border-radius: 10px;
    color: var(--dw-text-2);
    border-color: var(--dw-border);
    background: var(--dw-surface);
}
html.v2 .dw-timeline-controls .dw-iconbtn:hover { background: var(--dw-surface-2); border-color: var(--dw-border-strong); color: var(--dw-text); }
html.v2 .dw-timeline-play.is-playing { background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent); }
/* Set while playback is waiting on the next frame to download, so a slow link
   reads as buffering rather than as a stuck player. */
html.v2 .dw-timeline-play.is-waiting .mdi { animation: dw-tl-waiting 1s ease-in-out infinite; }
@keyframes dw-tl-waiting {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}
html.v2 .dw-timeline-play.is-playing:hover { background: var(--dw-accent-2); color: var(--dw-on-accent); }
html.v2 .dw-timeline-now {
    font-size: 12.5px; color: var(--dw-muted); margin-left: 6px;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
html.v2 .dw-timeline-foot .dw-segmented { margin-left: auto; }

html.v2 .dw-btn-sm { height: 36px; padding: 0 11px; font-size: 12.5px; gap: 6px; }
html.v2 .dw-btn-block { display: flex; width: 100%; justify-content: center; margin-top: 12px; }

html.v2 .dw-timeline-custom {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
    margin-top: 14px; padding-top: 14px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-timeline-custom label {
    display: flex; flex-direction: column; gap: 5px;
    font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted);
}
html.v2 .dw-timeline-custom input {
    height: 36px; padding: 0 11px;
    border-radius: 10px; border: 1px solid var(--dw-border);
    background: var(--dw-surface-2); color: var(--dw-text);
    font-family: inherit; font-size: 13px;
}
html.v2 .dw-timeline-custom input:focus { outline: none; border-color: var(--dw-accent); background: var(--dw-surface); }

/* segmented control */
html.v2 .dw-segmented {
    display: inline-flex; padding: 3px; gap: 2px;
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    border-radius: 11px;
}
html.v2 .dw-segmented-btn {
    height: 28px; padding: 0 12px;
    border: 0; border-radius: 8px; cursor: pointer;
    background: transparent; color: var(--dw-text-2);
    font-family: inherit; font-size: 12.5px; font-weight: 600;
    transition: background .14s, color .14s;
    white-space: nowrap;
}
html.v2 .dw-segmented-btn:hover { color: var(--dw-text); }
html.v2 .dw-segmented-btn.is-active {
    background: var(--dw-accent); color: var(--dw-on-accent);
    box-shadow: 0 4px 12px -6px rgba(240, 160, 30, .9);
}

/* --- captures per day ---------------------------------------------------- */
html.v2 .dw-daybars-chart {
    display: flex; align-items: flex-end; gap: 3px;
    height: 76px; padding-top: 4px;
    /* Up to 93 bars at a 2px floor is wider than a phone; scroll rather than
       push the panel past the viewport. */
    overflow-x: auto;
    scrollbar-width: thin;
}
html.v2 .dw-daybar {
    flex: 1 0 2px; min-width: 2px;
    height: var(--dw-bar, 2%);
    border-radius: 3px 3px 1px 1px;
    background: var(--dw-accent);
    opacity: .82;
    transition: opacity .14s, height .3s ease;
}
html.v2 .dw-daybar:hover { opacity: 1; }
html.v2 .dw-daybar.is-zero { background: var(--dw-border-strong); opacity: .55; }

/* --- recent captures rail ------------------------------------------------ */
html.v2 .dw-shots-list { display: flex; flex-direction: column; gap: 6px; max-height: 460px; overflow-y: auto; margin: 0 -6px; padding: 0 6px; }
html.v2 .dw-shot {
    box-sizing: border-box;
    display: flex; align-items: center; gap: 11px;
    padding: 6px; border-radius: var(--dw-r);
    background: transparent; border: 1px solid transparent;
    cursor: pointer; text-align: left; width: 100%;
    font-family: inherit; color: var(--dw-text);
    transition: background .14s, border-color .14s;
}
html.v2 .dw-shot:hover { background: var(--dw-surface-2); border-color: var(--dw-border); }
html.v2 .dw-shot.is-current { background: var(--dw-accent-soft); border-color: var(--dw-accent); }
html.v2 .dw-shot-thumb {
    position: relative; flex: none;
    width: 84px; aspect-ratio: 16 / 10;
    border-radius: var(--dw-r-sm); overflow: hidden;
    background: var(--dw-surface-3);
}
html.v2 .dw-shot-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
html.v2 .dw-shot-body { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
html.v2 .dw-shot-body b { font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums; }
html.v2 .dw-shot-body span { font-size: 11.5px; color: var(--dw-muted); }
html.v2 .dw-shot.is-current .dw-shot-body b { color: var(--dw-accent-text); }

/* --- camera switcher ----------------------------------------------------- */
html.v2 .dw-cams { padding-bottom: 14px; }
html.v2 .dw-camlist { display: flex; flex-direction: column; gap: 2px; margin: 0 -8px; }
html.v2 .dw-camlist-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: 10px;
    color: var(--dw-text-2); font-size: 13.5px;
    min-width: 0;
}
html.v2 .dw-camlist-item:hover { background: var(--dw-surface-2); color: var(--dw-text); }
html.v2 .dw-camlist-item .mdi { font-size: 17px; opacity: .7; flex: none; }
html.v2 .dw-camlist-item > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.v2 .dw-camlist-item.is-current {
    background: var(--dw-accent-soft); color: var(--dw-accent-text); font-weight: 600;
}
html.v2 .dw-camlist-item.is-current .mdi { opacity: 1; }
html.v2 .dw-camlist-tick { font-size: 16px; }

/* --- quick actions grid -------------------------------------------------- */
html.v2 .dw-quick { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
html.v2 .dw-quick a {
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    padding: 12px 4px;
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    color: var(--dw-text-2);
    font-size: 11px; font-weight: 600; text-align: center;
    transition: background .14s, border-color .14s, color .14s, transform .14s;
}
html.v2 .dw-quick a:hover {
    background: var(--dw-accent-soft); border-color: var(--dw-accent);
    color: var(--dw-accent-text); transform: translateY(-2px);
}
html.v2 .dw-quick .mdi { font-size: 21px; line-height: 1; }
html.v2 .dw-quick span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* --- narrow screens ------------------------------------------------------ */
@media (max-width: 720px) {
    /* The top bar wraps its search onto a second line here, so the fixed rail
       and its backdrop — both anchored to this token — have to clear the taller
       bar rather than start underneath it. */
    html.v2 { --dw-topbar-h: 104px; }

    html.v2 .dw-timeline-foot .dw-segmented { margin-left: 0; width: 100%; overflow-x: auto; }
    html.v2 .dw-projsel-btn { max-width: 150px; }
}


/* --------------------------------------------------------------------------
   20. Schedule request page
   --------------------------------------------------------------------
   /schedule. The camera service exposes three capture windows; the page
   presents them as the three parts of a week, with a live preview beside the
   form of what is about to be requested.
   -------------------------------------------------------------------------- */
html.v2 .dw-tag-mute { background: var(--dw-surface-3); color: var(--dw-muted); }

/* .dw-panel-head aligns on the baseline, which is right for a title plus a
   note and wrong for a title sitting next to a 34px icon tile. */
html.v2 .dw-panel-head.is-iconed { align-items: center; flex-wrap: nowrap; }

html.v2 .dw-switch-label { font-size: 13px; font-weight: 600; color: var(--dw-text-2); }
html.v2 .dw-switch-lg .dw-switch-track { width: 52px; height: 30px; border-radius: 999px; }
html.v2 .dw-switch-lg .dw-switch-track::after { width: 24px; height: 24px; top: 3px; left: 3px; }
html.v2 .dw-switch-lg input:checked + .dw-switch-track::after { transform: translateX(22px); }

/* number input with a trailing unit */
html.v2 .dw-suffixed { position: relative; }
html.v2 .dw-suffixed .uk-input { padding-right: 74px; }
html.v2 .dw-suffixed > span {
    position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
    font-size: 12.5px; color: var(--dw-muted); pointer-events: none;
}

/* --- hero ---------------------------------------------------------------- */
html.v2 .dw-schedhero {
    position: relative;
    /* Wraps so the call-to-action drops under the copy rather than squeezing
       it on a narrow screen. */
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 20px 24px;
    min-height: 150px;
    padding: 26px clamp(20px, 3vw, 34px);
    margin: 0 0 20px;
    border-radius: var(--dw-r-lg);
    overflow: hidden;
    background: var(--dw-rail);
    color: #fff;
}
html.v2 .dw-schedhero-shot {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    width: 100%; height: 100%; object-fit: cover;
    /* Right-weighted, so the heading keeps a flat dark ground to sit on. */
    -webkit-mask-image: linear-gradient(90deg, transparent 34%, #000 78%);
    mask-image: linear-gradient(90deg, transparent 34%, #000 78%);
}
html.v2 .dw-schedhero > *:not(.dw-schedhero-shot) { position: relative; z-index: 2; }
html.v2 .dw-schedhero-body { flex: 1 1 340px; min-width: 0; }
html.v2 .dw-schedhero h1 {
    margin: 0 0 8px;
    color: #fff;
    font-size: clamp(22px, 2.8vw, 30px);
    letter-spacing: -.025em;
}
html.v2 .dw-schedhero p {
    margin: 0;
    max-width: 52ch;
    color: rgba(255, 255, 255, .8);
    font-size: 13.5px;
}
/* The accent link colour is unreadable on this dark ground. */
html.v2 .dw-schedhero p a { color: #fff; text-decoration: underline; text-underline-offset: 2px; }
html.v2 .dw-schedhero p a:hover { color: var(--dw-accent); }

/* A single call to action, in place of the brand mark. */
html.v2 .dw-schedhero-actions { flex: none; display: flex; flex-wrap: wrap; gap: 10px; }
html.v2 .dw-schedhero-mark {
    margin: 0; flex: none; text-align: right;
    text-shadow: 0 1px 10px rgba(0, 0, 0, .7);
}
html.v2 .dw-schedhero-mark b {
    display: block;
    font-size: 12px; font-weight: 700;
    letter-spacing: .28em; text-transform: uppercase;
    color: #fff;
}
html.v2 .dw-schedhero-mark span {
    display: block; margin-top: 8px;
    font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
    color: var(--dw-accent);
}
@media (max-width: 820px) {
    html.v2 .dw-schedhero-mark { display: none; }
    html.v2 .dw-schedhero-shot {
        -webkit-mask-image: linear-gradient(90deg, transparent 10%, #000 120%);
        mask-image: linear-gradient(90deg, transparent 10%, #000 120%);
    }
}

/* --- camera picker ------------------------------------------------------- */
html.v2 .dw-schedpick {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px 18px;
    padding: 14px 18px;
    margin: 0 0 20px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
}
html.v2 .dw-schedpick-ico {
    flex: none;
    width: 46px; height: 46px;
    display: grid; place-items: center;
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
    color: var(--dw-muted);
}
html.v2 .dw-schedpick-ico .mdi { font-size: 22px; line-height: 1; }
html.v2 .dw-schedpick-field { flex: 1 1 320px; min-width: 0; }
html.v2 .dw-schedpick-note { font-size: 12.5px; color: var(--dw-muted); }

/* --- layout -------------------------------------------------------------- */
html.v2 .dw-schedlayout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
@media (min-width: 1100px) {
    html.v2 .dw-schedlayout { grid-template-columns: minmax(0, 1fr) 320px; }
    /* The action bar spans both columns and closes the form off. */
    html.v2 .dw-schedbar { grid-column: 1 / -1; }
}
html.v2 .dw-schedlayout-main { min-width: 0; }
html.v2 .dw-schedlayout-side { min-width: 0; }

/* --- numbered step ------------------------------------------------------- */
html.v2 .dw-step {
    position: relative;
    padding: 18px 20px 18px 62px;
    margin: 0 0 16px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
}
html.v2 .dw-step:last-child { margin-bottom: 0; }
html.v2 .dw-step-num {
    position: absolute; left: 18px; top: 18px;
    width: 28px; height: 28px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--dw-accent); color: var(--dw-on-accent);
    font-size: 13px; font-weight: 700;
}
html.v2 .dw-step-head {
    display: flex; align-items: center; flex-wrap: wrap; gap: 12px 20px;
    justify-content: space-between;
}
html.v2 .dw-step-title { margin: 0; font-size: 15.5px; font-weight: 650; }
html.v2 .dw-step-note { margin: 3px 0 0; font-size: 12.5px; color: var(--dw-muted); }
html.v2 .dw-step-body { margin-top: 16px; }
html.v2 .dw-step.is-off { opacity: .5; }
html.v2 .dw-step.is-off .dw-step-body { pointer-events: none; }

/* --- one capture window -------------------------------------------------- */
html.v2 .dw-schedrow {
    padding: 14px 16px;
    margin-bottom: 12px;
    border: 1px solid var(--dw-border);
    border-left: 3px solid var(--dw-border-strong);
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
}
html.v2 .dw-schedrow:last-child { margin-bottom: 0; }
html.v2 .dw-schedrow.is-weekday  { border-left-color: var(--dw-info-text); }
html.v2 .dw-schedrow.is-saturday { border-left-color: var(--dw-good); }
html.v2 .dw-schedrow.is-sunday   { border-left-color: var(--dw-accent); }

html.v2 .dw-schedrow-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
html.v2 .dw-schedrow-ico {
    flex: none; width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: var(--dw-r-sm);
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    color: var(--dw-muted);
}
html.v2 .dw-schedrow-ico .mdi { font-size: 18px; line-height: 1; }
html.v2 .dw-schedrow.is-weekday  .dw-schedrow-ico { color: var(--dw-info-text); }
html.v2 .dw-schedrow.is-saturday .dw-schedrow-ico { color: var(--dw-good-text); }
html.v2 .dw-schedrow.is-sunday   .dw-schedrow-ico { color: var(--dw-accent-text); }
html.v2 .dw-schedrow-id { flex: 1; min-width: 0; display: flex; flex-direction: column; }
html.v2 .dw-schedrow-id b { font-size: 14px; font-weight: 650; }
html.v2 .dw-schedrow-id span { font-size: 12px; color: var(--dw-muted); }
html.v2 .dw-schedrow-switch { flex: none; }

html.v2 .dw-schedrow-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px 14px;
}
html.v2 .dw-schedrow-fields.is-dates { grid-template-columns: repeat(2, minmax(140px, 170px)); }


html.v2 .dw-schedrow-note { margin: 12px 0 0; font-size: 12px; color: var(--dw-muted); }

/* --- preview ------------------------------------------------------------- */
html.v2 .dw-prevrow {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--dw-border);
}
html.v2 .dw-prevrow:last-of-type { border-bottom: 0; }
html.v2 .dw-prevrow-id { min-width: 0; display: flex; flex-direction: column; }
html.v2 .dw-prevrow-id b { font-size: 13px; font-weight: 650; }
html.v2 .dw-prevrow-id span { font-size: 11.5px; color: var(--dw-muted); }
html.v2 .dw-prevrow-val { text-align: right; min-width: 0; display: flex; flex-direction: column; }
html.v2 .dw-prevrow-val b { font-size: 13px; font-weight: 600; white-space: nowrap; }
html.v2 .dw-prevrow-val span { font-size: 11.5px; color: var(--dw-muted); white-space: nowrap; }

html.v2 .dw-schedhelp { display: flex; align-items: flex-start; gap: 12px; }
html.v2 .dw-schedhelp > div { min-width: 0; }
html.v2 .dw-schedhelp b { display: block; font-size: 13.5px; font-weight: 650; margin-bottom: 4px; }
html.v2 .dw-schedhelp p { margin: 0; font-size: 12.5px; color: var(--dw-muted); }

/* --- action bar ---------------------------------------------------------- */
html.v2 .dw-schedbar {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    flex-wrap: wrap;
    padding: 14px 18px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
}
html.v2 .dw-schedbar .uk-button { min-width: 150px; }

/* --- profile ------------------------------------------------------------- */
/* The page is built from the four panels ProfileComponent wraps, used
   directly. Their markup is the classic page's — <label>Text<input></label>,
   .uk-margin, an <h5> per upload panel — so most of this is teaching that
   markup the v2 form rhythm. The components themselves are shared and
   untouched. */
html.v2 .dw-profilelayout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
@media (min-width: 1080px) {
    html.v2 .dw-profilelayout { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); }
    html.v2 .dw-profilelayout-side { position: sticky; top: calc(var(--dw-topbar-h) + 20px); }
}
html.v2 .dw-profilelayout > * { min-width: 0; }

/* Two cards abreast on a wide screen, stacked below it. */
html.v2 .dw-profilegrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    margin-bottom: 20px;
    align-items: start;
}
@media (min-width: 1400px) {
    html.v2 .dw-profilegrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
html.v2 .dw-profilegrid > * { min-width: 0; }
html.v2 .dw-profilegrid:last-child { margin-bottom: 0; }

/* --- identity card --- */
html.v2 .dw-idcard { text-align: center; }
html.v2 .dw-idcard-figure {
    width: 128px; height: 128px;
    margin: 4px auto 16px;
    display: grid; place-items: center;
    border-radius: 22px;
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    overflow: hidden;
}
html.v2 .dw-idcard-figure img { max-width: 84%; max-height: 84%; width: auto; height: auto; object-fit: contain; }
html.v2 .dw-idcard-initial {
    font-size: 46px; font-weight: 700; line-height: 1;
    color: var(--dw-accent-2);
}
html.v2 .dw-idcard-name { margin: 0 0 10px; font-size: 18px; font-weight: 650; letter-spacing: -.015em; }
html.v2 .dw-idcard-kv {
    margin: 20px 0 0;
    padding-top: 16px;
    border-top: 1px solid var(--dw-border);
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    text-align: left;
}
html.v2 .dw-idcard-kv dd { overflow-wrap: anywhere; }

/* --- the panels' own markup --- */
html.v2 .dw-profileform .dw-card-body > div > .uk-margin:first-child { margin-top: 0; }
html.v2 .dw-profileform .uk-margin { margin-bottom: 16px; }
html.v2 .dw-profileform .uk-margin:last-child { margin-bottom: 0; }
/* Each field is a <label> wrapping its own input. */
html.v2 .dw-profileform label {
    display: block;
    font-size: 12.5px; font-weight: 600; color: var(--dw-text-2);
}
html.v2 .dw-profileform label + label { margin-top: 14px; }
html.v2 .dw-profileform label > .uk-input { margin-top: 6px; }
/* The card head already names each panel. */
html.v2 .dw-profileform h5 { display: none; }
html.v2 .dw-profileform .uk-button { min-width: 140px; }
html.v2 .dw-profileform .sc-form-errors-list {
    margin-top: 6px; font-size: 12px; color: var(--dw-bad-text);
}

/* --- image croppers --- */
html.v2 .dw-profileform .img-cropper {
    max-width: 100%;
    margin-bottom: 14px;
    border-radius: var(--dw-r);
    overflow: hidden;
    background: var(--dw-surface-2);
    border: 1px dashed var(--dw-border-strong);
}
/* cropperjs only builds a box once an image is set; until then the wrapper
   would be an empty hairline rectangle. */
html.v2 .dw-profileform .img-cropper:empty,
html.v2 .dw-profileform .img-cropper img:not([src]) { display: none; }
html.v2 .dw-profileform .img-cropper img { max-width: 100%; display: block; }
html.v2 .dw-profileform .cropper-container { max-height: 320px; }
html.v2 .dw-profileform [uk-form-custom] { display: inline-block; vertical-align: middle; }
html.v2 .dw-profileform [uk-form-custom] .uk-input { cursor: pointer; }

/* The asset a panel is about to replace. */
html.v2 .dw-assetnow {
    position: relative;
    display: flex; align-items: center; justify-content: center;
    min-height: 96px; padding: 14px;
    margin-bottom: 16px;
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
    border: 1px solid var(--dw-border);
    overflow: hidden;
}
html.v2 .dw-assetnow img { max-width: 100%; max-height: 110px; width: auto; display: block; }
html.v2 .dw-assetnow-label {
    position: absolute; top: 8px; left: 10px;
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--dw-muted);
}

/* --- daily diary --------------------------------------------------------- */
/* Delivery is a short, fixed set of fields; the camera list is the part that
   grows with the account, so it takes the width. */
html.v2 .dw-diarylayout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
@media (min-width: 1080px) {
    html.v2 .dw-diarylayout { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); }
}
html.v2 .dw-diarylayout > * { min-width: 0; }
html.v2 .dw-diaryactions { margin-top: 20px; }

/* --------------------------------------------------------------------------
   21. Time lapse page
   --------------------------------------------------------------------
   /time-lapse. The build form and the render queue are the same Vue
   components the classic page mounts, so most of this is re-laying their
   markup out down one column instead of across a navbar.
   -------------------------------------------------------------------------- */

/* underline tabs */
html.v2 .dw-tabs {
    display: flex; align-items: center; gap: 4px;
    margin: 0 0 20px;
    border-bottom: 1px solid var(--dw-border);
    overflow-x: auto;
}
html.v2 .dw-tab {
    position: relative;
    display: inline-flex; align-items: center; gap: 8px;
    height: 38px; padding: 0 4px; margin-right: 18px;
    border: 0; background: none; cursor: pointer;
    color: var(--dw-muted);
    font-family: var(--dw-font); font-size: 13.5px; font-weight: 600;
    white-space: nowrap;
    transition: color .14s;
}
html.v2 .dw-tab:hover { color: var(--dw-text-2); }
html.v2 .dw-tab.is-active { color: var(--dw-accent-text); }
html.v2 .dw-tab.is-active::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: -1px;
    height: 2px; border-radius: 2px 2px 0 0;
    background: var(--dw-accent);
}
html.v2 .dw-tab .dw-count {
    font-size: 11px; font-weight: 650; padding: 1px 7px; border-radius: 999px;
    background: var(--dw-surface-2); color: var(--dw-muted); border: 1px solid var(--dw-border);
}
/* "2 renders in progress", pinned to the end of the tab strip so the state of
   the queue is readable from whichever tab is open. */
html.v2 .dw-tabs-note {
    display: inline-flex; align-items: center; gap: 6px;
    margin-left: auto; padding-left: 16px;
    font-size: 12.5px; font-weight: 600; color: var(--dw-accent-text);
    white-space: nowrap;
}
html.v2 .dw-tabs-note .mdi { font-size: 15px; line-height: 1; }

html.v2 .dw-tllayout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
html.v2 .dw-tllayout > * { min-width: 0; }
@media (min-width: 1000px) {
    html.v2 .dw-tllayout { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); }
}

/* --- build form ---------------------------------------------------------- */
/* CreateTimeLapseFormComponent renders a UIkit card with a three-across grid
   and a navbar of actions. In one narrow column all of that becomes a single
   stack; the component itself is shared with the classic page and untouched. */
html.v2 .dw-tlcreate .uk-card {
    background: none; border: 0; box-shadow: none; border-radius: 0;
}
html.v2 .dw-tlcreate .uk-card-body { padding: 0; }
html.v2 .dw-tlcreate .uk-heading-line { display: none; }
html.v2 .dw-tlcreate .uk-grid { margin-left: 0; }
html.v2 .dw-tlcreate .uk-grid > * { width: 100%; padding-left: 0; }
/* A spacer div the component leaves in the grid; it has whitespace in it,
   so :empty does not reach it. */
html.v2 .dw-tlcreate .uk-grid > .uk-float-right { display: none; }
html.v2 .dw-tlcreate .uk-grid > * + * { margin-top: 14px; }
html.v2 .dw-tlcreate label {
    display: block; margin-bottom: 6px;
    font-size: 12.5px; font-weight: 600; color: var(--dw-text-2);
}
html.v2 .dw-tlcreate .uk-navbar-container,
html.v2 .dw-tlcreate .uk-navbar { background: none; min-height: 0; }
html.v2 .dw-tlcreate nav[uk-navbar],
html.v2 .dw-tlcreate nav.uk-navbar-container {
    display: flex; flex-direction: column; align-items: stretch; gap: 10px;
    margin-top: 18px; padding-top: 16px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-tlcreate .uk-navbar-left,
html.v2 .dw-tlcreate .uk-navbar-right {
    display: flex; flex-direction: column; align-items: stretch; gap: 10px;
    width: 100%; min-height: 0;
}
/* The component spaces its actions with .uk-padding-small; down one column
   that is a gap, not padding. */
html.v2 .dw-tlcreate .uk-padding-small { padding: 0; }
html.v2 .dw-tlcreate .uk-button,
html.v2 .dw-tlcreate .uk-input,
html.v2 .dw-tlcreate .uk-select { width: 100%; min-width: 0; }
/* The component's two preset buttons carry a full sentence ("Last month full
   timelapse (1st-30th) 7am to 5pm"). .uk-button is nowrap and auto-sizes to
   its text, so in this column the label decided the width and pushed the whole
   form past the panel. Here they wrap and grow downwards instead. */
html.v2 .dw-tlcreate .uk-button {
    height: auto; min-height: 40px;
    padding: 10px 16px;
    white-space: normal;
    line-height: 1.35;
    text-align: center;
}
html.v2 .dw-tlcreate .uk-float-right { float: none; }
html.v2 .dw-tlcreate .uk-navbar-right .uk-button-primary { height: 42px; font-size: 14px; }
html.v2 .dw-tlcreate .dw-tool { margin-bottom: 16px; }
html.v2 .dw-tlcreate .dw-tool:first-of-type { margin-top: 4px; }

/* --- preview ------------------------------------------------------------- */
html.v2 .dw-tlpreview-meta { margin: 0 0 14px; font-size: 13px; color: var(--dw-muted); }
html.v2 .dw-tlpreview-meta b { color: var(--dw-text); font-weight: 600; }
html.v2 .dw-tlpreview-frame {
    border-radius: var(--dw-r);
    overflow: hidden;
    background: #000;
    aspect-ratio: 16 / 9;
}
html.v2 .dw-tlpreview-frame video { display: block; width: 100%; height: 100%; object-fit: contain; }
html.v2 .dw-tlpreview-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }

/* --- what a render was built with ---------------------------------------- */
html.v2 .dw-tlparams { margin: 0 0 14px; }
html.v2 .dw-tlparams > summary {
    display: flex; align-items: center; gap: 10px;
    cursor: pointer; list-style: none;
}
html.v2 .dw-tlparams > summary::-webkit-details-marker { display: none; }
html.v2 .dw-tlparams-open {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; font-weight: 600; color: var(--dw-muted);
}
html.v2 .dw-tlparams-open .mdi { font-size: 15px; line-height: 1; }
html.v2 .dw-tlparams > summary:hover .dw-tlparams-open { color: var(--dw-text-2); }
html.v2 .dw-tlparams[open] > summary { margin-bottom: 12px; }

html.v2 .dw-tlparams-group + .dw-tlparams-group { margin-top: 14px; }
html.v2 .dw-tlparams-group h3 {
    margin: 0 0 6px; font-size: 11px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase; color: var(--dw-muted);
}
html.v2 .dw-tlparams-group dl {
    display: grid; grid-template-columns: minmax(0, 9.5rem) minmax(0, 1fr);
    gap: 4px 14px; margin: 0; font-size: 12.5px;
}
html.v2 .dw-tlparams-group dt { color: var(--dw-muted); }
html.v2 .dw-tlparams-group dd { margin: 0; color: var(--dw-text-2); }
html.v2 .dw-tlparams-group dd small { display: block; font-size: 11.5px; color: var(--dw-muted); }
@media (max-width: 560px) {
    html.v2 .dw-tlparams-group dl { grid-template-columns: minmax(0, 1fr); gap: 0; }
    html.v2 .dw-tlparams-group dd { margin-bottom: 7px; }
}

html.v2 .dw-empty-sm { padding: 36px 20px; }
html.v2 .dw-empty-sm .mdi { font-size: 30px; }
html.v2 .dw-empty-sm h2 { font-size: 15px; }
html.v2 .dw-empty-sm p { font-size: 13px; }


/* --------------------------------------------------------------------------
   22. Image search page
   --------------------------------------------------------------------
   /image-search/{project}. A year of capture days as a heat calendar, the
   picked day's images as a contact sheet, and a lightbox over the top. All of
   it is drawn by initImageSearch() in v2.js from one JSON payload, so the
   classes below are the contract between that function and this sheet.
   -------------------------------------------------------------------------- */

html.v2 .dw-isstats { margin-bottom: 20px; }
/* A date is not a number — it wants the body size, not the 26px stat size. */
html.v2 .dw-stat-value-sm { font-size: 17px; letter-spacing: -.01em; }

/* --- calendar ------------------------------------------------------------ */
html.v2 .dw-cal-head { align-items: center; }
/* The base sheet pushes a trailing .dw-panel-note to the right edge. Here it
   is a subtitle for the title beside it, and the year picker owns the end of
   the row — so both selectors have to be matched to undo it. */
html.v2 .dw-cal-head .dw-panel-note,
html.v2 .dw-cal-head .dw-panel-note:last-child { margin-right: auto; margin-left: 0; }
html.v2 .dw-cal-years { flex: none; max-width: 100%; overflow-x: auto; }

html.v2 .dw-cal-filters { margin: 2px 0 16px; }
html.v2 .dw-cal-latest { flex: none; margin-left: auto; }
@media (max-width: 640px) {
    html.v2 .dw-cal-latest { margin-left: 0; }
}

/* Twelve month blocks. 196px is the narrowest a month reads at: seven columns
   plus the gaps still leave a 23px day cell, which holds two digits. */
html.v2 .dw-calgrid,
html.v2 .dw-calskel {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
    gap: 18px 20px;
}
html.v2 .dw-calskel { grid-column: 1 / -1; }

html.v2 .dw-calmonth { min-width: 0; }
html.v2 .dw-calmonth-head {
    display: flex; align-items: baseline; gap: 8px;
    margin: 0 0 7px; padding-bottom: 6px;
    border-bottom: 1px solid var(--dw-border);
}
html.v2 .dw-calmonth-name { font-size: 12.5px; font-weight: 650; letter-spacing: -.01em; }
html.v2 .dw-calmonth-count {
    margin-left: auto;
    font-size: 11px; font-weight: 600; color: var(--dw-muted);
    font-variant-numeric: tabular-nums;
}
/* A month with nothing in it stays in the grid so the year keeps its shape —
   it just stops asking for attention. */
html.v2 .dw-calmonth.is-empty { opacity: .5; }

html.v2 .dw-caldow,
html.v2 .dw-caldays { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
html.v2 .dw-caldow {
    margin-bottom: 3px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--dw-muted); text-align: center;
}

html.v2 .dw-calday {
    display: grid; place-items: center;
    aspect-ratio: 1; min-width: 0;
    padding: 0; border: 0; border-radius: 5px;
    background: var(--dw-surface-2);
    color: var(--dw-muted);
    font-family: inherit; font-size: 10.5px; font-weight: 600; line-height: 1;
    font-variant-numeric: tabular-nums;
    transition: transform .12s ease, box-shadow .12s ease;
}
html.v2 .dw-calday.is-pad { background: none; }
/* A day with no captures is not a target — it is rendered as a span, so it
   never takes tab focus and never looks clickable. */
html.v2 .dw-calday.is-none { background: var(--dw-surface-3); opacity: .7; }
html.v2 .dw-calday.is-future { background: none; box-shadow: inset 0 0 0 1px var(--dw-border); opacity: .55; }

html.v2 button.dw-calday { cursor: pointer; }
html.v2 button.dw-calday:hover { transform: scale(1.16); box-shadow: var(--dw-shadow-1); }
html.v2 button.dw-calday:focus-visible { outline: 2px solid var(--dw-info); outline-offset: 1px; }

/* The fill ramp. Levels 1-3 are the accent at low alpha, so the day number
   stays --dw-text and legible on either ground; only the top level flips to
   the solid accent and its own text colour. The dark ramp is lighter-handed
   on purpose: the same alphas over a near-black surface land mid-brown, where
   neither black nor white text clears AA. */
html.v2 .dw-calday.is-l1 { background: rgba(240, 160, 30, .18); color: var(--dw-text); }
html.v2 .dw-calday.is-l2 { background: rgba(240, 160, 30, .38); color: var(--dw-text); }
html.v2 .dw-calday.is-l3 { background: rgba(240, 160, 30, .66); color: var(--dw-text); }
html.v2 .dw-calday.is-l4 { background: var(--dw-accent); color: var(--dw-on-accent); }
html.v2[data-dw-theme="dark"] .dw-calday.is-l1 { background: rgba(240, 160, 30, .14); }
html.v2[data-dw-theme="dark"] .dw-calday.is-l2 { background: rgba(240, 160, 30, .30); }
html.v2[data-dw-theme="dark"] .dw-calday.is-l3 { background: rgba(240, 160, 30, .52); }

html.v2 .dw-calday.is-today { box-shadow: inset 0 0 0 1.5px var(--dw-info); }
html.v2 .dw-calday.is-selected {
    box-shadow: 0 0 0 2px var(--dw-bg), 0 0 0 4px var(--dw-accent-2);
    transform: scale(1.1);
}
html.v2 button.dw-calday.is-selected:hover { transform: scale(1.18); }

html.v2 .dw-cal-none { margin: 4px 0 0; padding: 26px 0; text-align: center; font-size: 13px; color: var(--dw-muted); }

html.v2 .dw-cal-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; }
html.v2 .dw-cal-legend-scale {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; color: var(--dw-muted);
}
html.v2 .dw-cal-legend .dw-calday {
    display: inline-block;
    width: 13px; height: 13px; aspect-ratio: auto;
}
html.v2 .dw-cal-legend-note { font-size: 11.5px; color: var(--dw-muted); margin-left: auto; }
@media (max-width: 760px) {
    html.v2 .dw-cal-legend-note { margin-left: 0; }
}

/* --- results: the picked day's contact sheet ----------------------------- */
html.v2 .dw-isres { scroll-margin-top: calc(var(--dw-topbar-h) + 16px); }
html.v2 .dw-isres-head { align-items: flex-start; }
html.v2 .dw-isres-title { flex: 1 1 240px; min-width: 0; }
html.v2 .dw-isres-title .dw-panel-note { margin: 4px 0 0; }
html.v2 .dw-isres-actions { display: flex; flex-wrap: wrap; gap: 8px; flex: none; }

html.v2 .dw-iscams { margin: 0 0 16px; }
html.v2 .dw-iscams:empty { display: none; }
html.v2 .dw-iscams .dw-chip { height: 32px; font-size: 12.5px; }

html.v2 .dw-isgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
    gap: 12px;
}
html.v2 .dw-isgrid.is-busy { opacity: .5; pointer-events: none; }
html.v2 .dw-isgrid:empty { display: none; }

html.v2 .dw-isshot { position: relative; margin: 0; min-width: 0; }
html.v2 .dw-isshot-btn {
    display: block; width: 100%; padding: 0;
    background: none; border: 0; cursor: pointer;
    border-radius: var(--dw-r); overflow: hidden;
    box-shadow: inset 0 0 0 1px var(--dw-border);
    transition: box-shadow .14s, transform .14s;
}
html.v2 .dw-isshot-btn:hover { box-shadow: inset 0 0 0 1px var(--dw-border-strong), var(--dw-shadow-2); transform: translateY(-2px); }
html.v2 .dw-isshot-btn:focus-visible { outline: 2px solid var(--dw-info); outline-offset: 2px; }
html.v2 .dw-isshot .dw-media { border-radius: var(--dw-r); }
html.v2 .dw-isshot-time {
    position: absolute; left: 8px; bottom: 8px; z-index: 2;
    font-variant-numeric: tabular-nums;
}
html.v2 .dw-isshot-kind { position: absolute; left: 8px; top: 8px; z-index: 2; }

/* The tick only shows on hover, on focus, or once it is on — an unchecked box
   on every frame turns the sheet into a form. */
html.v2 .dw-isshot-pick {
    position: absolute; right: 8px; top: 8px; z-index: 3;
    display: grid; place-items: center;
    width: 26px; height: 26px; border-radius: 8px;
    background: rgba(10, 13, 18, .5);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, .2);
    cursor: pointer;
    opacity: 0; transition: opacity .14s;
}
html.v2 .dw-isshot:hover .dw-isshot-pick,
html.v2 .dw-isshot-pick:focus-within,
html.v2 .dw-isshot.is-picked .dw-isshot-pick { opacity: 1; }
html.v2 .dw-isshot-pick input { margin: 0 !important; }
html.v2 .dw-isshot.is-picked .dw-isshot-btn { box-shadow: inset 0 0 0 2px var(--dw-accent); }

/* Selection bar. Sticky inside the panel so it stays reachable on a long
   sheet without floating over the rest of the page. */
html.v2 .dw-isbar {
    position: sticky; bottom: 10px; z-index: 4;
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
    margin: 16px 0 0; padding: 10px 14px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border-strong);
    border-radius: 999px;
    box-shadow: var(--dw-shadow-2);
}
html.v2 .dw-isbar-count { font-size: 13px; font-weight: 600; color: var(--dw-text-2); margin-right: auto; }
html.v2 .dw-isbar-all { height: 32px; font-size: 12.5px; }
html.v2 .dw-isbar-dl { position: relative; flex: none; }
html.v2 .dw-isbar-menu { bottom: calc(100% + 8px); top: auto; min-width: 220px; }

html.v2 .dw-isplaceholder { margin-bottom: 20px; }

/* --- lightbox ------------------------------------------------------------ */
/* Over TV mode (200), under the toast (300) — a download that finishes while
   the viewer is open should still be able to say so. */
html.v2 .dw-lightbox {
    position: fixed; inset: 0; z-index: 250;
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) 64px;
    grid-template-rows: auto minmax(0, 1fr);
    background: rgba(6, 8, 12, .95);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
/* The page behind must not scroll under the viewer — the arrow keys belong to
   the viewer while it is open, and a wheel over the scrim should do nothing. */
html.v2.dw-lb-open, html.v2.dw-lb-open body { overflow: hidden; }

html.v2 .dw-lightbox-bar {
    grid-column: 1 / -1; grid-row: 1;
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px;
    color: #fff;
}
html.v2 .dw-lightbox-meta { display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
html.v2 .dw-lightbox-meta b { font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; }
html.v2 .dw-lightbox-meta span { font-size: 12px; color: rgba(255, 255, 255, .62); }
html.v2 .dw-lightbox-count {
    margin-left: auto;
    font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, .62);
    font-variant-numeric: tabular-nums;
}
/* The shell buttons are built for light panels; over the scrim they need the
   dark-glass treatment instead. */
html.v2 .dw-lightbox .dw-btn,
html.v2 .dw-lightbox .dw-btn-icon {
    background: rgba(255, 255, 255, .1);
    border-color: rgba(255, 255, 255, .18);
    color: #fff;
}
html.v2 .dw-lightbox .dw-btn:hover,
html.v2 .dw-lightbox .dw-btn-icon:hover {
    background: rgba(255, 255, 255, .18);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}

/* Stretches to fill its grid area (the default align-self) so the image's
   max-height has something definite to resolve against; the nav buttons centre
   themselves instead. */
html.v2 .dw-lightbox-stage {
    grid-column: 2; grid-row: 2;
    position: relative;
    margin: 0; padding: 0 0 20px;
    display: grid; place-items: center;
    min-height: 0; min-width: 0;
}
html.v2 .dw-lightbox-stage img,
html.v2 .dw-lightbox-stage video {
    max-width: 100%; max-height: 100%;
    object-fit: contain;
    border-radius: var(--dw-r);
    background: #000;
}
html.v2 .dw-lightbox-stage img[hidden],
html.v2 .dw-lightbox-stage video[hidden] { display: none; }

html.v2 .dw-lightbox-nav {
    grid-row: 2; align-self: center;
    display: grid; place-items: center;
    width: 48px; height: 48px; margin: 0 auto;
    border: 0; border-radius: 50%;
    background: rgba(255, 255, 255, .1); color: #fff;
    cursor: pointer;
    transition: background .14s, opacity .14s;
}
html.v2 .dw-lightbox-nav:hover { background: rgba(255, 255, 255, .2); }
html.v2 .dw-lightbox-nav:disabled { opacity: .25; cursor: default; }
html.v2 .dw-lightbox-nav .mdi { font-size: 28px; line-height: 1; }
html.v2 .dw-lightbox-nav.is-prev { grid-column: 1; }
html.v2 .dw-lightbox-nav.is-next { grid-column: 3; }

html.v2 .dw-lightbox-spin {
    position: absolute; width: 34px; height: 34px;
    border-radius: 50%;
    border: 3px solid rgba(255, 255, 255, .22);
    border-top-color: #fff;
    animation: dwSpin .8s linear infinite;
}
@keyframes dwSpin { to { transform: rotate(360deg); } }

@media (max-width: 640px) {
    html.v2 .dw-lightbox { grid-template-columns: 40px minmax(0, 1fr) 40px; }
    html.v2 .dw-lightbox-nav { width: 36px; height: 36px; }
    html.v2 .dw-lightbox-nav .mdi { font-size: 22px; }
    html.v2 .dw-lightbox-bar { flex-wrap: wrap; gap: 8px; }
    html.v2 .dw-lightbox-count { order: 3; margin-left: 0; }
}

/* ==========================================================================
   Modal shell — feature request, service enquiry
   --------------------------------------------------------------------------
   UIkit draws the dialog; these rules give it the v2 skin and the header
   layout the two forms share. Everything is scoped to .dw-modal so the
   existing uk-modal dialogs elsewhere in the app are untouched.
   ========================================================================== */
html.v2 .dw-modal .dw-modal-dialog {
    width: 620px; max-width: calc(100vw - 32px);
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-3);
    color: var(--dw-text);
    overflow: hidden;
}
html.v2 .dw-modal .uk-modal-close-default { color: var(--dw-muted); }
html.v2 .dw-modal .uk-modal-close-default:hover { color: var(--dw-text); }

html.v2 .dw-modal-head {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 26px 28px 18px;
    background: var(--dw-surface);
    border-bottom: 1px solid var(--dw-border);
}
html.v2 .dw-modal-ico {
    flex: none;
    width: 42px; height: 42px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 12px;
    background: var(--dw-accent-soft); color: var(--dw-accent-2);
}
html.v2 .dw-modal-ico .mdi { font-size: 22px; line-height: 1; }
html.v2 .dw-modal .uk-modal-title {
    margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -.02em;
    color: var(--dw-text);
}
html.v2 .dw-modal-lede { margin: 6px 0 0; font-size: 14px; font-weight: 600; color: var(--dw-text-2); }
html.v2 .dw-modal-note { margin: 6px 0 0; font-size: 13.5px; line-height: 1.6; color: var(--dw-muted); }

html.v2 .dw-modal .uk-modal-body { padding: 20px 28px; background: var(--dw-surface); }
html.v2 .dw-modal .uk-modal-body > * + * { margin-top: 16px; }

html.v2 .dw-modal-hint {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    background: var(--dw-info-soft);
    font-size: 13px; line-height: 1.55; color: var(--dw-text-2);
}
html.v2 .dw-modal-hint .mdi { flex: none; font-size: 18px; line-height: 1.4; color: var(--dw-info); }

html.v2 .dw-modal-foot {
    display: flex; justify-content: flex-end; gap: 10px;
    padding: 16px 28px 22px;
    background: var(--dw-surface-2);
    border-top: 1px solid var(--dw-border);
}

html.v2 .dw-kv-tight dt, html.v2 .dw-kv-tight dd { padding-top: 4px; padding-bottom: 4px; }

@media (max-width: 640px) {
    html.v2 .dw-modal-head { padding: 20px 18px 14px; }
    html.v2 .dw-modal .uk-modal-body { padding: 16px 18px; }
    html.v2 .dw-modal-foot { padding: 14px 18px 18px; }
    html.v2 .dw-modal .uk-modal-title { font-size: 19px; }
}

/* ==========================================================================
   Schedule request — project bar and camera picker
   ========================================================================== */
html.v2 .dw-schedinfo {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0;
    margin: 18px 0;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
    overflow: hidden;
}
html.v2 .dw-schedinfo-cell {
    display: flex; align-items: center; gap: 12px;
    padding: 16px 18px;
    min-width: 0;
}
html.v2 .dw-schedinfo-cell + .dw-schedinfo-cell { border-left: 1px solid var(--dw-border); }
html.v2 .dw-schedinfo-ico {
    flex: none;
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 10px;
    background: var(--dw-surface-3); color: var(--dw-text-2);
}
html.v2 .dw-schedinfo-ico .mdi { font-size: 18px; line-height: 1; }
html.v2 .dw-schedinfo-ico.is-good { background: var(--dw-good-soft); color: var(--dw-good-text); }
html.v2 .dw-schedinfo-ico.is-warn { background: var(--dw-warn-soft); color: var(--dw-warn-text); }
html.v2 .dw-schedinfo-ico.is-bad { background: var(--dw-bad-soft); color: var(--dw-bad-text); }
html.v2 .dw-schedinfo-ico.is-sleep { background: var(--dw-sleep-soft); color: var(--dw-sleep-text); }
html.v2 .dw-schedinfo-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
html.v2 .dw-schedinfo-label {
    font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted);
}
html.v2 .dw-schedinfo-body b {
    font-size: 14px; font-weight: 650; color: var(--dw-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

@media (max-width: 960px) {
    html.v2 .dw-schedinfo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    html.v2 .dw-schedinfo-cell:nth-child(odd) { border-left: 0; }
    html.v2 .dw-schedinfo-cell:nth-child(n+3) { border-top: 1px solid var(--dw-border); }
}
@media (max-width: 560px) {
    html.v2 .dw-schedinfo { grid-template-columns: minmax(0, 1fr); }
    html.v2 .dw-schedinfo-cell + .dw-schedinfo-cell { border-left: 0; border-top: 1px solid var(--dw-border); }
}

html.v2 .dw-step-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
html.v2 .dw-step-count { font-size: 12.5px; color: var(--dw-muted); font-variant-numeric: tabular-nums; }
html.v2 .dw-step-optional { font-size: 13px; font-weight: 500; color: var(--dw-muted); }
html.v2 .dw-step-hint {
    margin: 14px 0 0; padding: 10px 12px;
    border-radius: var(--dw-r-sm);
    background: var(--dw-accent-soft);
    font-size: 12.5px; color: var(--dw-text-2);
}
html.v2 .dw-check-strong { padding: 7px 11px; font-weight: 600; }

/* --- camera picker cards --- */
html.v2 .dw-camsel {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px;
}
html.v2 .dw-camsel-card {
    position: relative;
    display: flex; flex-direction: column;
    border: 2px solid var(--dw-border);
    border-radius: var(--dw-r);
    background: var(--dw-surface-2);
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s, box-shadow .15s, background .15s;
}
html.v2 .dw-camsel-card:hover { border-color: var(--dw-border-strong); }
html.v2 .dw-camsel-card.is-on {
    border-color: var(--dw-accent);
    background: var(--dw-surface);
    box-shadow: 0 0 0 3px var(--dw-accent-soft);
}
/* Visually hidden rather than display:none, so it stays focusable and the
   whole card remains a real label for it. */
html.v2 .dw-camsel-check {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden;
}
html.v2 .dw-camsel-card:focus-within { border-color: var(--dw-accent); }

html.v2 .dw-camsel-media {
    position: relative; display: block;
    aspect-ratio: 16 / 10;
    background: var(--dw-surface-3);
}
html.v2 .dw-camsel-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
html.v2 .dw-camsel-tick {
    position: absolute; top: 9px; left: 9px;
    width: 22px; height: 22px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 6px;
    border: 2px solid rgba(255, 255, 255, .85);
    background: rgba(13, 17, 23, .45);
    color: transparent;
}
html.v2 .dw-camsel-tick .mdi { font-size: 15px; line-height: 1; }
html.v2 .dw-camsel-card.is-on .dw-camsel-tick {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent);
}
html.v2 .dw-camsel-pill { position: absolute; top: 9px; right: 9px; }

html.v2 .dw-camsel-body { display: flex; flex-direction: column; gap: 3px; padding: 12px 13px 13px; }
html.v2 .dw-camsel-name { font-size: 14px; font-weight: 650; color: var(--dw-text); }
html.v2 .dw-camsel-project {
    display: flex; align-items: center; gap: 5px; min-width: 0;
    font-size: 12px; font-weight: 600; color: var(--dw-text-2);
}
html.v2 .dw-camsel-project .mdi { flex: none; font-size: 14px; line-height: 1; color: var(--dw-muted); }
html.v2 .dw-camsel-sub { font-size: 12px; color: var(--dw-muted); }
html.v2 .dw-camsel-sched {
    display: flex; flex-direction: column; gap: 2px;
    margin-top: 9px; padding-top: 9px;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-camsel-sched span {
    font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted);
}
html.v2 .dw-camsel-sched b { font-size: 12.5px; font-weight: 600; color: var(--dw-text-2); }

/* --- "applies to" --- */
html.v2 .dw-applies { margin-top: 14px; }
html.v2 .dw-applies-label {
    display: block; margin-bottom: 8px;
    font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--dw-muted);
}
html.v2 .dw-applies-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
html.v2 .dw-applies-list li {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--dw-text-2);
}
html.v2 .dw-applies-list li .dw-dot { flex: none; }
html.v2 .dw-applies-list li.is-good .dw-dot { background: var(--dw-good); }
html.v2 .dw-applies-list li.is-warn .dw-dot { background: var(--dw-warn); }
html.v2 .dw-applies-list li.is-bad .dw-dot { background: var(--dw-bad); }
html.v2 .dw-applies-list li.is-sleep .dw-dot { background: var(--dw-sleep); }
html.v2 .dw-applies-state { color: var(--dw-muted); font-size: 12px; }
html.v2 .dw-applies-empty { color: var(--dw-muted); font-size: 12.5px; }

/* ==========================================================================
   Media pages — drone images, ground photography, events, drone videos
   ========================================================================== */
/* --- page head --- */
html.v2 .dw-mediapage-title { display: flex; align-items: center; gap: 14px; min-width: 0; }
html.v2 .dw-mediapage-ico {
    flex: none; width: 50px; height: 50px; border-radius: 15px;
    display: grid; place-items: center;
    background: var(--dw-accent-soft); color: var(--dw-accent-2);
}
html.v2[data-dw-theme="dark"] .dw-mediapage-ico { color: var(--dw-accent); }
html.v2 .dw-mediapage-ico .mdi { font-size: 28px; line-height: 1; }

/* --- picker + content --- */
html.v2 .dw-medialayout {
    display: grid;
    grid-template-columns: minmax(270px, 350px) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
html.v2 .dw-mediamain { min-width: 0; }
/* Beside the picker the month bar has a column, not the page, so the chips
   tighten up enough for a whole year to fit at desktop widths. */
html.v2 .dw-mediamain .dw-monthset { gap: 2px; }
html.v2 .dw-mediamain .dw-monthchip { min-width: 40px; padding: 5px 5px; }

/* The picker stays in view while the month below it scrolls, and scrolls its
   own list when a customer has more projects than fit. */
html.v2 .dw-mediapick {
    margin: 0;
    position: sticky; top: calc(var(--dw-topbar-h) + 16px);
    max-height: calc(100vh - var(--dw-topbar-h) - 32px);
    display: flex; flex-direction: column;
    padding: 18px 16px;
}
html.v2 .dw-mediapick-head { padding: 0 4px; }
html.v2 .dw-mediapick-head .dw-panel-title { font-size: 17px; }
html.v2 .dw-mediapick-head .dw-panel-note { display: block; margin-top: 3px; font-size: 12.5px; }
html.v2 .dw-mediapick-tabs {
    display: grid; grid-template-columns: 1fr 1fr;
    margin: 14px 0 12px;
}
html.v2 .dw-mediapick-tabs .dw-segmented-btn { height: 34px; }
html.v2 .dw-mediapick-search { display: block; margin: 0 0 12px; }
html.v2 .dw-mediapick-search .uk-input { width: 100%; height: 38px; font-size: 13px; }

html.v2 .dw-mediapick-list {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    display: flex; flex-direction: column; gap: 8px;
    margin: 0 -4px; padding: 2px 4px; list-style: none;
    scrollbar-width: thin;
}

html.v2 .dw-mediapick-card {
    display: grid; grid-template-columns: 92px minmax(0, 1fr); align-items: center; gap: 12px;
    padding: 8px 10px 8px 8px;
    border: 1px solid var(--dw-border); border-radius: var(--dw-r);
    background: var(--dw-surface); color: var(--dw-text); text-decoration: none;
    transition: border-color .14s, background .14s, box-shadow .14s;
}
html.v2 .dw-mediapick-card:hover { border-color: var(--dw-border-strong); background: var(--dw-surface-2); color: var(--dw-text); }
html.v2 .dw-mediapick-card:focus-visible { outline: 2px solid var(--dw-accent); outline-offset: 2px; }
html.v2 .dw-mediapick-card.is-current {
    border-color: var(--dw-accent);
    background: var(--dw-accent-soft);
    box-shadow: 0 0 0 1px var(--dw-accent) inset;
}
html.v2 .dw-mediapick-thumb { width: 92px; aspect-ratio: 4 / 3; border-radius: var(--dw-r-sm); }
html.v2 .dw-mediapick-thumb::after { display: none; }
html.v2 .dw-mediapick-thumb .dw-media-blank .mdi { font-size: 20px; }
html.v2 .dw-mediapick-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
html.v2 .dw-mediapick-name {
    font-size: 13.5px; font-weight: 650; line-height: 1.3; color: var(--dw-text);
    overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
html.v2 .dw-mediapick-meta { font-size: 12px; color: var(--dw-muted); display: flex; align-items: center; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
html.v2 .dw-mediapick-cadence { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--dw-text-2); }
html.v2 .dw-mediapick-cadence .mdi { font-size: 14px; line-height: 1; color: var(--dw-muted); }
/* Solid, not the soft tint: it sits on a photo. */
html.v2 .dw-mediapick-new {
    position: absolute; z-index: 1; top: 5px; left: 5px;
    padding: 1px 7px; font-size: 10.5px;
    background: var(--dw-accent); color: var(--dw-on-accent);
}
html.v2 .dw-mediapick-none { padding: 10px 4px; font-size: 13px; color: var(--dw-muted); list-style: none; }
html.v2 p.dw-mediapick-none { margin: 0; }

/* --- the chosen project --- */
html.v2 .dw-mediasum {
    display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px;
    margin: 0 0 16px; padding: 14px 18px 14px 14px;
}
html.v2 .dw-mediasum-thumb { flex: none; width: 128px; aspect-ratio: 4 / 3; border-radius: var(--dw-r); }
html.v2 .dw-mediasum-thumb::after { display: none; }
html.v2 .dw-mediasum-id { flex: 1 1 220px; min-width: 0; }
html.v2 .dw-mediasum-name { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; }
html.v2 .dw-mediasum-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 8px 0 0; font-size: 12.5px; color: var(--dw-text-2); }
html.v2 .dw-mediasum-sub > span:not(.dw-tag) { display: inline-flex; align-items: center; gap: 5px; }
html.v2 .dw-mediasum-sub .mdi { font-size: 15px; line-height: 1; color: var(--dw-muted); }
html.v2 .dw-mediasum-stats { display: flex; flex-wrap: wrap; gap: 14px 26px; }
html.v2 .dw-mediasum-stat { display: flex; align-items: center; gap: 9px; }
html.v2 .dw-mediasum-stat > .mdi { font-size: 20px; line-height: 1; color: var(--dw-muted); }
html.v2 .dw-mediasum-stat > span { display: flex; flex-direction: column; line-height: 1.25; }
html.v2 .dw-mediasum-stat b { font-size: 17px; font-weight: 700; color: var(--dw-text); white-space: nowrap; }
html.v2 .dw-mediasum-stat small { font-size: 11.5px; color: var(--dw-muted); white-space: nowrap; }

/* Below this the picker goes above the content as one scrolling row, rather
   than squeezing the month into a column beside it. */
@media (max-width: 1100px) {
    html.v2 .dw-medialayout { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    html.v2 .dw-mediapick { position: static; max-height: none; }
    html.v2 .dw-mediapick-list {
        flex-direction: row; overflow-x: auto; overflow-y: hidden;
        padding-bottom: 6px;
    }
    html.v2 .dw-mediapick-list > li { flex: 0 0 min(300px, 82vw); }
}
@media (max-width: 640px) {
    html.v2 .dw-mediasum-thumb { width: 96px; }
    html.v2 .dw-mediasum-name { font-size: 18px; }
    html.v2 .dw-mediasum-stats { width: 100%; gap: 12px 18px; }
}

/* --- month bar --- */
html.v2 .dw-monthbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-1);
}
html.v2 .dw-monthbar-year {
    flex: none; height: 38px; padding: 0 10px;
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-sm);
    background: var(--dw-surface-2); color: var(--dw-text);
    font-family: inherit; font-size: 13px; font-weight: 600;
    cursor: pointer;
}
html.v2 .dw-monthbar-months { flex: 1 1 420px; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
html.v2 .dw-monthset { display: flex; gap: 4px; }
html.v2 .dw-monthset[hidden] { display: none; }

html.v2 .dw-monthchip {
    flex: none;
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    min-width: 46px; padding: 5px 8px;
    border: 1px solid transparent;
    border-radius: var(--dw-r-sm);
    color: var(--dw-text-2); text-decoration: none;
    transition: background .14s, color .14s, border-color .14s;
}
html.v2 .dw-monthchip b { font-size: 12px; font-weight: 650; }
html.v2 .dw-monthchip span { font-size: 11px; color: var(--dw-muted); font-variant-numeric: tabular-nums; }
html.v2 a.dw-monthchip:hover { background: var(--dw-surface-2); border-color: var(--dw-border); color: var(--dw-text); }
html.v2 .dw-monthchip.is-active {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent);
}
html.v2 .dw-monthchip.is-active span { color: rgba(35, 24, 6, .7); }
html.v2 .dw-monthchip.is-empty { opacity: .38; cursor: default; }

html.v2 .dw-monthbar-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
html.v2 .dw-search-sm .uk-input { height: 38px; width: 200px; font-size: 13px; }
html.v2 .dw-select-sm { height: 38px; width: auto; min-width: 130px; font-size: 13px; }

@media (max-width: 720px) {
    html.v2 .dw-monthbar-tools { margin-left: 0; width: 100%; }
    html.v2 .dw-search-sm .uk-input { width: 100%; }
    html.v2 .dw-search-sm { flex: 1 1 160px; }
}

/* --- month heading --- */
html.v2 .dw-mediahead {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
    margin: 22px 0 14px;
}
html.v2 .dw-mediahead-title {
    margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: var(--dw-text);
    display: flex; align-items: baseline; gap: 10px;
}
html.v2 .dw-mediahead-count { font-size: 13px; font-weight: 500; color: var(--dw-muted); font-variant-numeric: tabular-nums; }
html.v2 .dw-mediahead-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
html.v2 .dw-mediahead-tools .dw-segmented-btn { padding: 0 10px; }
html.v2 .dw-mediahead-tools .dw-segmented-btn .mdi { font-size: 16px; line-height: 1; }
html.v2 .dw-menuwrap { position: relative; }
html.v2 #dw-media-select.is-active {
    background: var(--dw-accent-soft); border-color: var(--dw-accent); color: var(--dw-accent-text);
}

/* --- the grid --- */
html.v2 .dw-mediagrid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px;
}
html.v2 .dw-mediatile {
    position: relative;
    display: flex; flex-direction: column;
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r);
    background: var(--dw-surface);
    box-shadow: var(--dw-shadow-1);
    overflow: hidden;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
html.v2 .dw-mediatile:hover { border-color: var(--dw-border-strong); transform: translateY(-2px); }
html.v2 .dw-mediatile[hidden] { display: none; }

html.v2 .dw-mediatile-media {
    position: relative; display: block;
    width: 100%; padding: 0; border: 0;
    aspect-ratio: 16 / 10;
    background: var(--dw-surface-3);
    cursor: pointer;
}
html.v2 .dw-mediatile-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
html.v2 .dw-mediatile-play {
    position: absolute; inset: 0; margin: auto;
    width: 52px; height: 52px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: rgba(13, 17, 23, .55);
    border: 2px solid rgba(255, 255, 255, .85);
    color: #fff;
}
html.v2 .dw-mediatile-play .mdi { font-size: 26px; line-height: 1; margin-left: 3px; }

html.v2 .dw-mediatile-foot {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 11px;
    font-size: 12.5px; color: var(--dw-text-2);
    min-width: 0;
}
html.v2 .dw-mediatile-date { display: flex; align-items: center; gap: 6px; font-weight: 600; white-space: nowrap; }
html.v2 .dw-mediatile-date .mdi { font-size: 15px; opacity: .55; }
html.v2 .dw-mediatile-time { color: var(--dw-muted); font-variant-numeric: tabular-nums; }
html.v2 .dw-mediatile-spacer { flex: 1; min-width: 0; }
html.v2 .dw-mediatile-cam {
    min-width: 0;
    font-size: 11.5px; color: var(--dw-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Direct save, on the video pages only — the still pages zip instead. */
html.v2 .dw-mediatile-get {
    flex: none;
    width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 7px;
    color: var(--dw-muted);
    transition: background .14s, color .14s;
}
html.v2 .dw-mediatile-get:hover { background: var(--dw-surface-3); color: var(--dw-text); }
html.v2 .dw-mediatile-get .mdi { font-size: 16px; line-height: 1; }

/* selection */
html.v2 .dw-mediatile-pick { position: absolute; top: 9px; left: 9px; z-index: 2; display: none; cursor: pointer; }
html.v2 .dw-mediagrid.is-selecting .dw-mediatile-pick { display: block; }
html.v2 .dw-mediatile-pick input {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden;
}
html.v2 .dw-mediatile-pick > span {
    display: flex; align-items: center; justify-content: center;
    width: 24px; height: 24px;
    border-radius: 7px;
    border: 2px solid rgba(255, 255, 255, .85);
    background: rgba(13, 17, 23, .45);
    color: transparent;
}
html.v2 .dw-mediatile-pick .mdi { font-size: 16px; line-height: 1; }
html.v2 .dw-mediatile.is-picked { border-color: var(--dw-accent); box-shadow: 0 0 0 3px var(--dw-accent-soft); }
html.v2 .dw-mediatile.is-picked .dw-mediatile-pick > span {
    background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-on-accent);
}

/* list view: the same tiles, laid out as rows */
html.v2 .dw-mediagrid[data-view="list"] { grid-template-columns: minmax(0, 1fr); gap: 8px; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile { flex-direction: row; align-items: center; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile:hover { transform: none; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile-media { width: 132px; flex: none; aspect-ratio: 16 / 10; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile-play { width: 34px; height: 34px; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile-play .mdi { font-size: 18px; }
html.v2 .dw-mediagrid[data-view="list"] .dw-mediatile-foot { flex: 1; padding: 12px 14px; gap: 14px; }

/* selection bar */
html.v2 .dw-selbar {
    position: sticky; bottom: 16px; z-index: 30;
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    margin-top: 16px; padding: 10px 14px;
    background: var(--dw-surface);
    border: 1px solid var(--dw-border-strong);
    border-radius: var(--dw-r-lg);
    box-shadow: var(--dw-shadow-2);
}
html.v2 .dw-selbar-count { font-size: 13px; color: var(--dw-text-2); }
html.v2 .dw-selbar-count b { font-variant-numeric: tabular-nums; color: var(--dw-text); }
html.v2 .dw-selbar-spacer { flex: 1; }

/* ==========================================================================
   Service promotion — what a project without drone / ground / video sees
   ========================================================================== */
html.v2 .dw-promo-head {
    display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px;
    margin: 6px 0 26px;
}
html.v2 .dw-promo-title {
    margin: 0; font-size: 38px; font-weight: 700; letter-spacing: -.03em; color: var(--dw-text);
}
html.v2 .dw-promo-sub { margin: 8px 0 0; font-size: 15px; color: var(--dw-text-2); }
html.v2 .dw-promo-mark {
    margin: 6px 0 0 auto;
    display: flex; align-items: center; gap: 14px;
    text-align: right;
}
html.v2 .dw-promo-mark .mdi { font-size: 40px; color: var(--dw-text-2); opacity: .7; }
html.v2 .dw-promo-mark span { display: flex; flex-direction: column; line-height: 1.3; }
html.v2 .dw-promo-mark b {
    font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: -.01em;
    color: var(--dw-text);
}
html.v2 .dw-promo-mark em {
    font-style: normal; font-size: 15px; font-weight: 700; text-transform: uppercase;
    color: var(--dw-accent);
}

html.v2 .dw-promo-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px;
}
html.v2 .dw-promo-card {
    position: relative;
    display: flex; flex-direction: column;
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-r-lg);
    background: var(--dw-surface);
    box-shadow: var(--dw-shadow-1);
    overflow: hidden;
}
/* The card the customer actually clicked through to is lifted, so the row
   answers the heading above it rather than reading as three equal options. */
html.v2 .dw-promo-card.is-wanted {
    border-color: var(--dw-accent);
    box-shadow: 0 0 0 3px var(--dw-accent-soft), var(--dw-shadow-2);
}
/* .dw-media is overflow:hidden, which clipped off the half of the round badge
   below that hangs past the photo. The card is the one doing the rounding
   here, so the photo itself has nothing left to clip. */
html.v2 .dw-promo-shot {
    position: relative; aspect-ratio: 16 / 9;
    background: var(--dw-surface-3);
    overflow: visible;
}
html.v2 .dw-promo-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
html.v2 .dw-promo-ico {
    position: absolute; bottom: -26px; left: 20px; z-index: 2;
    width: 52px; height: 52px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--dw-rail); color: var(--dw-accent);
    border: 2px solid var(--dw-accent);
}
html.v2 .dw-promo-ico .mdi { font-size: 26px; line-height: 1; }

html.v2 .dw-promo-body { display: flex; flex-direction: column; flex: 1; padding: 34px 20px 20px; }
html.v2 .dw-promo-name { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.02em; color: var(--dw-text); }
html.v2 .dw-promo-note { margin: 5px 0 0; font-size: 13.5px; color: var(--dw-muted); }
html.v2 .dw-promo-list { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: 9px; flex: 1; }
html.v2 .dw-promo-list li {
    display: flex; align-items: flex-start; gap: 9px;
    font-size: 13.5px; color: var(--dw-text-2);
}
html.v2 .dw-promo-list .mdi { flex: none; font-size: 17px; line-height: 1.35; color: var(--dw-accent); }
html.v2 .dw-promo-cta { margin-top: 18px; justify-content: center; }

html.v2 .dw-promo-why {
    position: relative; overflow: hidden;
    display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    align-items: center; gap: 30px;
    margin-top: 22px; padding: 28px;
    border-radius: var(--dw-r-xl);
    background: var(--dw-rail);
    color: #fff;
}
html.v2 .dw-promo-why-shot {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .28;
}
html.v2 .dw-promo-why::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(100deg, rgba(10, 12, 16, .96) 0%, rgba(10, 12, 16, .86) 55%, rgba(10, 12, 16, .5) 100%);
}
html.v2 .dw-promo-why-lede, html.v2 .dw-promo-why-grid, html.v2 .dw-promo-why-mark { position: relative; z-index: 1; }
html.v2 .dw-promo-eyebrow {
    display: block; margin-bottom: 8px;
    font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
    color: rgba(255, 255, 255, .55);
}
html.v2 .dw-promo-why-lede h2 {
    margin: 0; font-size: 26px; font-weight: 700; letter-spacing: -.025em; color: #fff;
}
html.v2 .dw-promo-why-lede h2 em { font-style: normal; color: var(--dw-accent); }
html.v2 .dw-promo-why-lede p { margin: 10px 0 0; font-size: 13.5px; line-height: 1.6; color: rgba(255, 255, 255, .66); }

html.v2 .dw-promo-why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 22px; }
html.v2 .dw-promo-why-grid > div { display: flex; flex-direction: column; gap: 4px; }
html.v2 .dw-promo-why-grid .mdi { font-size: 22px; color: rgba(255, 255, 255, .85); margin-bottom: 4px; }
html.v2 .dw-promo-why-grid b { font-size: 13.5px; font-weight: 650; color: #fff; }
html.v2 .dw-promo-why-grid span { font-size: 12.5px; line-height: 1.5; color: rgba(255, 255, 255, .6); }

html.v2 .dw-promo-why-mark {
    position: absolute; right: 26px; bottom: 20px;
    margin: 0; text-align: right;
    font-size: 15px; font-style: italic; line-height: 1.3;
    color: rgba(255, 255, 255, .5);
}

@media (max-width: 1100px) {
    html.v2 .dw-promo-why { grid-template-columns: minmax(0, 1fr); }
    html.v2 .dw-promo-why-mark { display: none; }
}
@media (max-width: 760px) {
    html.v2 .dw-promo-title { font-size: 28px; }
    html.v2 .dw-promo-mark { display: none; }
    html.v2 .dw-promo-why { padding: 20px; }
}

/* ==========================================================================
   AI usage & costs (admin)
   --------------------------------------------------------------------------
   The chart's two module colours are validated as a pair (dataviz
   validate_palette.js) against each theme's surface: light #da7d02 / #2f6feb,
   dark #cf7600 / #4f86f0. Estimated cost is the same hue under a 45° hatch,
   so it never depends on colour alone.
   ========================================================================== */
html.v2 {
    --dw-series-ppe: #da7d02;
    --dw-series-excavator: #2f6feb;
    --dw-series-mute: #78849a;
}
html.v2[data-dw-theme="dark"] {
    --dw-series-ppe: #cf7600;
    --dw-series-excavator: #4f86f0;
    --dw-series-mute: #8794a8;
}

html.v2 .dw-usage-filters { gap: 10px 12px; }
html.v2 .dw-usage-filters .dw-segmented-btn { display: inline-flex; align-items: center; text-decoration: none; }
html.v2 .dw-usage-field { display: inline-flex; }
html.v2 .dw-usage-custom { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
html.v2 .dw-usage-custom input.uk-input { width: auto; min-width: 150px; }
html.v2 .dw-usage-dash { color: var(--dw-muted); }

html.v2 .dw-usage-stats { margin-bottom: 20px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
html.v2 .dw-usage-stats .dw-stat-value { font-size: 24px; }

/* --- cost per day ------------------------------------------------------- */
html.v2 .dw-costchart-legend {
    display: flex; flex-wrap: wrap; gap: 6px 16px;
    margin: 0 0 0 auto; padding: 0; list-style: none;
    font-size: 12px; color: var(--dw-text-2);
}
html.v2 .dw-costchart-legend li { display: inline-flex; align-items: center; gap: 7px; }
html.v2 .dw-costkey { width: 12px; height: 12px; border-radius: 3px; background: var(--dw-series-mute); }

html.v2 .dw-costseg.is-ppe, html.v2 .dw-costkey.is-ppe { background-color: var(--dw-series-ppe); }
html.v2 .dw-costseg.is-excavator, html.v2 .dw-costkey.is-excavator { background-color: var(--dw-series-excavator); }
html.v2 .dw-costkey.is-mute { background-color: var(--dw-series-mute); }
html.v2 .dw-costseg.is-est,
html.v2 .dw-costkey.is-est {
    background-image: repeating-linear-gradient(45deg,
        rgba(255, 255, 255, .55) 0 2px, transparent 2px 5px);
}
html.v2[data-dw-theme="dark"] .dw-costseg.is-est,
html.v2[data-dw-theme="dark"] .dw-costkey.is-est {
    background-image: repeating-linear-gradient(45deg,
        rgba(20, 24, 31, .6) 0 2px, transparent 2px 5px);
}

html.v2 .dw-costchart-plot {
    position: relative;
    height: 200px;
    margin-left: 64px;
}
html.v2 .dw-costchart-axis { position: absolute; inset: 0; pointer-events: none; }
html.v2 .dw-costchart-tick {
    position: absolute; left: 0; right: 0; height: 0;
    border-top: 1px solid var(--dw-border);
}
html.v2 .dw-costchart-tick b {
    position: absolute; right: calc(100% + 10px); top: -8px;
    font-size: 11px; font-weight: 500; color: var(--dw-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
html.v2 .dw-costchart-cols {
    position: absolute; inset: 0;
    display: flex; align-items: flex-end;
}
html.v2 .dw-costcol {
    flex: 1 1 0; min-width: 0; height: 100%;
    display: flex; align-items: flex-end; justify-content: center;
    padding: 0 1px;
    outline: none; cursor: default;
}
html.v2 .dw-costcol:focus-visible { box-shadow: inset 0 0 0 2px var(--dw-accent); border-radius: 4px; }
html.v2 .dw-costcol-stack {
    display: flex; flex-direction: column-reverse; gap: 2px;
    width: min(24px, 70%);
    min-height: 0;
    border-radius: 4px 4px 0 0;
    overflow: hidden;
    transition: filter .14s;
}
html.v2 .dw-costseg { display: block; flex-basis: 0; min-height: 1px; }
html.v2 .dw-costcol.is-hover .dw-costcol-stack { filter: brightness(1.12); }
html.v2 .dw-costcol.is-hover { background: var(--dw-surface-2); border-radius: 4px; }

/* First, middle and last day only; spread edge to edge, the middle one lands
   under the middle column. */
html.v2 .dw-costchart-x {
    display: flex; justify-content: space-between; gap: 8px;
    margin: 8px 0 0 64px;
    font-size: 11px; color: var(--dw-muted); font-variant-numeric: tabular-nums;
}
html.v2 .dw-costchart-x span { white-space: nowrap; }

html.v2 .dw-costchart-tip {
    position: absolute; top: 0; z-index: 5;
    transform: translate(-50%, -8px);
    min-width: 150px; padding: 9px 11px;
    background: var(--dw-surface); border: 1px solid var(--dw-border-strong);
    border-radius: var(--dw-r-sm); box-shadow: var(--dw-shadow-2);
    font-size: 12px; pointer-events: none;
}
html.v2 .dw-costchart-tip-head { display: flex; flex-direction: column; gap: 1px; }
html.v2 .dw-costchart-tip-head b { font-size: 15px; font-weight: 650; color: var(--dw-text); }
html.v2 .dw-costchart-tip-head span { color: var(--dw-muted); white-space: nowrap; }
html.v2 .dw-costchart-tip-row {
    display: flex; align-items: center; gap: 7px;
    margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--dw-border);
    white-space: nowrap;
}
html.v2 .dw-costchart-tip-row + .dw-costchart-tip-row { margin-top: 2px; padding-top: 0; border-top: 0; }
html.v2 .dw-costchart-tip-row b { color: var(--dw-text); font-weight: 650; font-variant-numeric: tabular-nums; }
html.v2 .dw-costchart-tip-row span { color: var(--dw-muted); }
html.v2 .dw-costline { display: inline-block; width: 12px; height: 2px; border-radius: 1px; background: var(--dw-series-mute); }
html.v2 .dw-costline.is-ppe { background: var(--dw-series-ppe); }
html.v2 .dw-costline.is-excavator { background: var(--dw-series-excavator); }

@media (max-width: 640px) {
    html.v2 .dw-costchart-plot, html.v2 .dw-costchart-x { margin-left: 52px; }
    html.v2 .dw-costchart-plot { height: 160px; }
}

/* --- per camera --------------------------------------------------------- */
html.v2 .dw-usage-cams .dw-table-scroll { margin: 0 -20px -18px; }
html.v2 .dw-usage-table th.is-num,
html.v2 .dw-usage-table td.is-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
html.v2 .dw-usage-table tfoot td {
    padding: 12px 16px; font-weight: 650; color: var(--dw-text);
    background: var(--dw-surface-2); border-top: 1px solid var(--dw-border);
}
html.v2 .dw-usage-table tr.is-idle td { color: var(--dw-muted); }
html.v2 .dw-usage-cam { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
html.v2 .dw-usage-cam b { color: var(--dw-text); font-weight: 600; }
html.v2 .dw-usage-sub { display: block; margin-top: 2px; font-size: 12px; color: var(--dw-muted); }
html.v2 .dw-usage-sharecol { width: 150px; }
html.v2 .dw-usage-share { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--dw-text-2); font-variant-numeric: tabular-nums; }
html.v2 .dw-usage-share > span:last-child { min-width: 34px; text-align: right; }
/* Meter: the track is a lighter step of the fill's own hue. */
html.v2 .dw-usage-meter { flex: 1; height: 6px; border-radius: 3px; background: var(--dw-accent-soft); overflow: hidden; }
html.v2 .dw-usage-meter > span { display: block; height: 100%; border-radius: 3px; background: var(--dw-series-ppe); }

/* --- pricing notes ------------------------------------------------------ */
html.v2 .dw-usage-notelist { margin: 0 0 12px; padding: 0; list-style: none; display: grid; gap: 12px; }
html.v2 .dw-usage-notelist li { display: flex; align-items: flex-start; gap: 12px; font-size: 13px; line-height: 1.55; color: var(--dw-text-2); }
html.v2 .dw-usage-notelist b { color: var(--dw-text); }
html.v2 .dw-usage-notelist code,
html.v2 .dw-usage-warn code {
    font-family: var(--dw-mono); font-size: 12px;
    padding: 1px 5px; border-radius: 4px; background: var(--dw-surface-3); color: var(--dw-text-2);
}
html.v2 .dw-usage-noteico {
    flex: none; width: 30px; height: 30px; border-radius: 9px;
    display: grid; place-items: center;
    background: var(--dw-accent-soft); color: var(--dw-accent-text);
}
html.v2 .dw-usage-noteico .mdi { font-size: 17px; line-height: 1; }
html.v2 .dw-usage-warn {
    display: flex; align-items: flex-start; gap: 8px;
    margin: 0 0 12px; padding: 10px 12px; border-radius: var(--dw-r-sm);
    background: var(--dw-warn-soft); color: var(--dw-warn-text); font-size: 13px;
}
html.v2 .dw-usage-warn .mdi { font-size: 17px; line-height: 1.3; }
