/*
 * Paper: the opt-in redesign (Settings key app.ui_design = "paper").
 *
 * Loaded after every other admin sheet on every page. Everything except the
 * design switch itself is scoped to :root[data-ui="paper"], which _base.html
 * sets on <html> only when the design is on, so the classic look is
 * untouched for everyone else.
 *
 * The approach is tokens first: the admin already reads its colours, type,
 * radii and shadows from the --t-* variables in base.css, so most of the
 * look changes by redefining them. The rest of this file turns the top bar
 * into a left sidebar on desktop (a left drawer on phones), flattens the
 * few places that draw thick borders or inset rings, and adds the motion.
 *
 * The fonts and the --t-* / --p-* tokens live in paper-tokens.css, loaded
 * just before this file.
 *
 * Rules: 1px hairlines at most, no shadows, no teal, monochrome navigation,
 * no serif. Panel previews keep their own colours.
 */

/* Settings cards carry their own palette in --dx-* variables, scoped to
   the card selectors. Point them at the tokens so they follow Paper (and
   its dark mode) instead of the classic teal-and-grey set. */
:root[data-ui="paper"] body * {
  --dx-teal: var(--t-accent);
  --dx-teal-hover: var(--t-accent-hover);
  --dx-ink: var(--t-fg);
  --dx-ink-soft: var(--t-fg-soft);
  --dx-faint: var(--t-muted);
  --dx-faint-2: var(--t-muted);
  --dx-border: var(--t-border);
  --dx-border-faint: var(--t-border);
  --dx-input-border: var(--t-border-strong);
  --dx-inset: var(--t-inset);
}

:root[data-ui="paper"] body { font-feature-settings: normal; }
/* Plain paper: no dotted grid behind the pages. */
:root[data-ui="paper"] body.admin { background-image: none; }

/* Navigation is monochrome in both layouts: no accent fill or underline
   on the active item (the sidebar/drawer rules below shade it instead). */
:root[data-ui="paper"] .topnav a.is-active::after,
:root[data-ui="paper"] .topnav .nav-dropdown.is-active summary::after { content: none; }
:root[data-ui="paper"] .topnav a.is-active,
:root[data-ui="paper"] .topnav .nav-dropdown.is-active summary,
:root[data-ui="paper"] .topnav .nav-dropdown[open] summary { color: var(--t-fg); background: var(--p-selected); }
:root[data-ui="paper"] :focus-visible { outline: 2px solid var(--p-focus); outline-offset: 2px; }

/* ----- Brand: the server mark and lockup (shell.css, base.css) -------- */

:root[data-ui="paper"] .brand { color: var(--t-fg); font-weight: 700; letter-spacing: -0.015em; }
:root[data-ui="paper"] .brand:hover { color: var(--t-fg); }
:root[data-ui="paper"] .brand-mark { transition: transform 220ms var(--p-ease); }
:root[data-ui="paper"] .brand:hover .brand-mark { transform: rotate(-6deg); }

/* ----- Shell: left sidebar on desktop -------------------------------- */

@media (min-width: 901px) {
  :root[data-ui="paper"] body.admin { padding-left: var(--p-sidebar-w); }
  :root[data-ui="paper"] .topbar {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--p-sidebar-w);
    box-sizing: border-box;
    flex-direction: column;
    align-items: stretch;
    gap: var(--t-space-1);
    padding: var(--t-space-5) var(--t-space-3) var(--t-space-4);
    background: var(--p-sidebar);
    border-bottom: 0;
    border-right: 1px solid var(--t-border);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  :root[data-ui="paper"] .topbar::before { content: none; }
  :root[data-ui="paper"] .brand { padding: 0 var(--t-space-2) var(--t-space-5); gap: 10px; }
    /* "Tesserae" and its SERVER tag on one line, the #350 name chip below. */
  :root[data-ui="paper"] .brand-name { display: flex; flex-direction: column; line-height: 1.1; font-size: 17px; }

  :root[data-ui="paper"] .topnav {
    flex: 1 0 auto;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 2px;
    margin: 0;
  }
  :root[data-ui="paper"] .topnav > a,
  :root[data-ui="paper"] .topnav .nav-dropdown > summary {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 40px;
    padding: 0 var(--t-space-3);
    border-radius: 0;
    color: var(--t-fg);
    font-size: 14px;
    font-weight: 500;
    background: transparent;
    transition: background-color 180ms ease-out;
  }
  :root[data-ui="paper"] .topnav > a .ph,
  :root[data-ui="paper"] .topnav .nav-dropdown > summary .ph { font-size: 19px; color: var(--t-fg-soft); }
  :root[data-ui="paper"] .topnav > a:hover,
  :root[data-ui="paper"] .topnav .nav-dropdown > summary:hover { background: var(--p-hover); color: var(--t-fg); }
  :root[data-ui="paper"] .topnav > a.is-active,
  :root[data-ui="paper"] .topnav .nav-dropdown.is-active > summary {
    background: var(--p-selected);
    color: var(--t-fg);
    font-weight: 600;
  }
  :root[data-ui="paper"] .topnav > a.is-active .ph,
  :root[data-ui="paper"] .topnav .nav-dropdown.is-active > summary .ph { color: var(--t-fg); }
  :root[data-ui="paper"] .topnav > a::after,
  :root[data-ui="paper"] .topnav .nav-dropdown.is-active summary::after { content: none; }
  :root[data-ui="paper"] .topnav .nav-dropdown .caret-soft { margin-left: auto; font-size: 13px; }
  /* Dropdowns open inline in the sidebar instead of floating. */
  :root[data-ui="paper"] .topnav .nav-dropdown-panel {
    position: static;
    min-width: 0;
    border: 0;
    border-left: 1px solid var(--t-border);
    border-radius: 0;
    background: transparent;
    margin: 2px 0 4px 21px;
    padding: 2px 0 2px 8px;
  }
  :root[data-ui="paper"] .topnav .nav-dropdown-link { padding: 8px 10px; font-size: 13px; color: var(--t-fg); }
  :root[data-ui="paper"] .topnav .nav-dropdown-link:hover { background: var(--p-hover); color: var(--t-fg); }

  /* Everything after the nav (update badge, new devices, batteries,
     opt-in, restart, theme) collects at the sidebar foot. */
  :root[data-ui="paper"] .topbar > .topbar-discovered--topbar,
  :root[data-ui="paper"] .topbar > .topbar-optin,
  :root[data-ui="paper"] .topbar > .topbar-restart-form,
  :root[data-ui="paper"] .topbar > .theme-toggle--topbar { margin: 0; align-self: flex-start; }
  :root[data-ui="paper"] .topbar > .theme-toggle--topbar { display: none; }
  :root[data-ui="paper"] .topnav .theme-toggle--drawer {
    display: inline-flex;
    width: 100%;
    height: 40px;
    gap: 12px;
    justify-content: flex-start;
    padding: 0 var(--t-space-3);
    margin-top: auto;
    border: 0;
    color: var(--t-fg-soft);
    font-size: 13px;
  }
  :root[data-ui="paper"] .topnav .theme-toggle--drawer .theme-toggle-label { display: inline; }
  :root[data-ui="paper"] .topnav .theme-toggle--drawer:hover { background: var(--p-hover); color: var(--t-fg); }
  /* The batteries leave the sidebar for the top-right corner (below).
     The drawer copy is a direct <a> of the nav, so the sidebar link
     rules above would otherwise lay its phone-only list out here. */
  :root[data-ui="paper"] .topnav > a.topbar-batteries--drawer { display: none; }
  :root[data-ui="paper"] .topbar > .topbar-batteries--topbar { position: fixed; top: 16px; right: 20px; margin: 0; }
  /* The pill gets a row of its own: pages start below it, so a page's
     title and its buttons never sit under it at rest. */
  :root[data-ui="paper"] body:has(.topbar > .topbar-batteries--topbar) main.page { padding-top: 68px; }
  :root[data-ui="paper"] .topbar-optin { flex-direction: column; align-items: stretch; gap: 4px; width: 100%; }

  /* Pages that stick to the top no longer need to clear a top bar. */
  :root[data-ui="paper"] .editor-header { top: 0; }
  /* ...but its actions run to the right edge, under the batteries pill. */
  :root[data-ui="paper"] body:has(.topbar > .topbar-batteries--topbar) .editor-header { padding-right: 112px; }
}

/* ----- Shell: the sidebar folds to an icon rail ---------------------- */
/* The toggle at the sidebar foot puts .sidebar-collapsed on <html> (the
   head script restores it before paint). Folded, the sidebar is the
   canvas editor's 64px rail: the logo and one 44px square per item, the
   labels gone (a tooltip names each item, see _base.html), dropdowns as
   flyouts to the right. Everything that measures from the sidebar
   (the page's left padding, the Settings column) follows the token. */
.sidebar-toggle,
.rail-tip { display: none; }
@media (min-width: 901px) {
  :root[data-ui="paper"].sidebar-collapsed { --p-sidebar-w: 64px; }
  /* Only while the toggle is moving it (the script sets the class for the
     length of the slide), so a page load never animates the sidebar in. */
  :root[data-ui="paper"].sidebar-sliding body.admin,
  :root[data-ui="paper"].sidebar-sliding .topbar,
  :root[data-ui="paper"].sidebar-sliding .settings-nav {
    transition: padding-left 200ms var(--p-ease), width 200ms var(--p-ease), left 200ms var(--p-ease);
  }

  :root[data-ui="paper"] .sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    width: 100%;
    height: 40px;
    flex: none;
    margin: 0;
    padding: 0 var(--t-space-3);
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    color: var(--t-fg-soft);
    font-size: 13px;
    font-weight: 500;
  }
  :root[data-ui="paper"] .sidebar-toggle:hover { background: var(--p-hover); color: var(--t-fg); transform: none; }
  :root[data-ui="paper"] .sidebar-toggle .ph { font-size: 19px; }

  :root[data-ui="paper"].sidebar-collapsed .topbar {
    align-items: center;
    padding: 14px 0;
    gap: 6px;
  }
  :root[data-ui="paper"].sidebar-collapsed .brand {
    width: 44px;
    height: 44px;
    padding: 0;
    margin-bottom: 12px;
    justify-content: center;
    gap: 0;
  }
  :root[data-ui="paper"].sidebar-collapsed .brand-mark,
  :root[data-ui="paper"].sidebar-collapsed .brand-mark svg { width: 30px; height: 30px; }
  :root[data-ui="paper"].sidebar-collapsed .brand-name { display: none; }
  :root[data-ui="paper"].sidebar-collapsed .topnav { align-items: center; gap: 6px; width: 100%; }
  /* Every item becomes a 44px square holding its icon. */
  :root[data-ui="paper"].sidebar-collapsed .topnav > a,
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown > summary,
  :root[data-ui="paper"].sidebar-collapsed .topnav .theme-toggle--drawer,
  :root[data-ui="paper"].sidebar-collapsed .topnav .ui-switch--nav,
  :root[data-ui="paper"].sidebar-collapsed .topbar > .topbar-discovered--topbar,
  :root[data-ui="paper"].sidebar-collapsed .topbar-restart,
  :root[data-ui="paper"].sidebar-collapsed .sidebar-toggle {
    position: relative;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    gap: 0;
    justify-content: center;
    align-self: center;
  }
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown { align-self: center; }
  :root[data-ui="paper"].sidebar-collapsed .topnav > a .ph,
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown > summary .ph { font-size: 20px; }
  :root[data-ui="paper"].sidebar-collapsed .topnav > a > span,
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown > summary > span,
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown .caret-soft,
  :root[data-ui="paper"].sidebar-collapsed .topnav .theme-toggle-label,
  :root[data-ui="paper"].sidebar-collapsed .topnav .ui-switch-label,
  :root[data-ui="paper"].sidebar-collapsed .topbar-discovered-label,
  :root[data-ui="paper"].sidebar-collapsed .topbar-restart-label,
  :root[data-ui="paper"].sidebar-collapsed .topbar-optin-no-label,
  :root[data-ui="paper"].sidebar-collapsed .topbar-optin-yes .topbar-restart-label,
  :root[data-ui="paper"].sidebar-collapsed .sidebar-toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* The update badges keep their dot on the icon's corner. */
  :root[data-ui="paper"].sidebar-collapsed .topnav > a.topbar-update .topbar-update-dot { position: absolute; top: 9px; right: 9px; margin: 0; }
  /* New devices: the count rides on the icon. */
  :root[data-ui="paper"].sidebar-collapsed .topbar > .topbar-discovered--topbar .tg-count {
    position: absolute;
    top: 4px;
    right: 2px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    font-size: 10px;
    line-height: 16px;
  }
  /* The design switch is just its track. */
  :root[data-ui="paper"].sidebar-collapsed .topnav .ui-switch--nav { border-radius: 0; }
  :root[data-ui="paper"].sidebar-collapsed .topnav .theme-toggle--drawer { margin-top: auto; }
  /* The opt-in prompt becomes two icon buttons, one under the other. */
  :root[data-ui="paper"].sidebar-collapsed .topbar-optin { width: 44px; align-self: center; align-items: center; }
  :root[data-ui="paper"].sidebar-collapsed .topbar-optin button { width: 44px; height: 44px; padding: 0; justify-content: center; }
  :root[data-ui="paper"].sidebar-collapsed .topbar-optin-no > .ph { display: inline-block; font-size: 18px; }
  /* The fold toggle flips to point back out. */
  :root[data-ui="paper"].sidebar-collapsed .sidebar-toggle-icon { transform: scaleX(-1); }

  /* Dropdowns fly out to the right of the rail. */
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown-panel {
    position: fixed;
    top: var(--flyout-top, 120px);
    left: calc(var(--p-sidebar-w) + 8px);
    z-index: 700;
    min-width: 220px;
    max-height: calc(100vh - 16px);
    overflow-y: auto;
    margin: 0;
    padding: 6px;
    border: 1px solid var(--p-sheet-edge);
    border-radius: 2px;
    background: var(--t-surface);
    box-shadow: none;
  }
  :root[data-ui="paper"].sidebar-collapsed .topnav .nav-dropdown-link { padding: 9px 10px; }

  /* The tooltip: a small ink label to the right of the rail. */
  :root[data-ui="paper"] .rail-tip {
    display: block;
    position: fixed;
    z-index: 800;
    transform: translateY(-50%);
    padding: 5px 9px;
    border-radius: 2px;
    background: var(--t-fg);
    color: var(--t-bg);
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
  }
  :root[data-ui="paper"] .rail-tip[hidden] { display: none; }
}
@media (min-width: 901px) and (prefers-reduced-motion: reduce) {
  :root[data-ui="paper"].sidebar-sliding body.admin,
  :root[data-ui="paper"].sidebar-sliding .topbar,
  :root[data-ui="paper"].sidebar-sliding .settings-nav { transition: none; }
}

/* ----- Shell: phones and small tablets ------------------------------- */

@media (max-width: 900px) {
  :root[data-ui="paper"] .topbar {
    background: var(--t-surface);
    border-bottom: 1px solid var(--t-border);
    padding-block: 8px;
    min-height: 56px;
    box-sizing: border-box;
  }
  :root[data-ui="paper"] .topbar::before { content: none; }
  :root[data-ui="paper"] .nav-toggle { border: 0; width: 44px; height: 44px; }
  /* The drawer comes in from the left, like the sidebar it stands in for. */
  :root[data-ui="paper"] .topnav {
    left: 0;
    right: auto;
    border-left: 0;
    border-right: 1px solid var(--t-border);
    transform: translateX(-100%);
    transition: transform 240ms var(--p-ease);
  }
  :root[data-ui="paper"] body.nav-open .topnav { transform: translateX(0); }
  :root[data-ui="paper"] .topnav a,
  :root[data-ui="paper"] .topnav .nav-dropdown summary { min-height: 44px; border-radius: 0; }
  :root[data-ui="paper"] .topnav a.is-active { background: var(--p-selected); color: var(--t-fg); font-weight: 600; }
  :root[data-ui="paper"] .topnav .nav-dropdown-panel { border-left-width: 1px; }
  :root[data-ui="paper"] .nav-scrim { background: rgba(28, 27, 25, 0.45); }
  /* The batteries pill sits in the bar beside the menu button, so the
     drawer drops its own copy of the list. */
  :root[data-ui="paper"] .topbar > .topbar-batteries--topbar { display: block; order: 1; margin-left: auto; }
  :root[data-ui="paper"] .topbar > .nav-toggle { order: 2; margin-left: 4px; }
  :root[data-ui="paper"] .topnav .topbar-batteries--drawer { display: none; }
}

/* ----- Batteries: a floating pill in the top-right corner ------------ */
/* The worst charge as an icon and a count (or the one percentage), on
   a round pill; the popover drops below it, right-aligned. */
:root[data-ui="paper"] .topbar > .topbar-batteries--topbar { z-index: 600; }
:root[data-ui="paper"] .topbar-batteries--topbar > summary,
:root[data-ui="paper"] a.topbar-batteries--topbar {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px 0 10px;
  box-sizing: border-box;
  border: 1px solid var(--t-border);
  border-radius: 999px;
  background: var(--t-surface);
  color: var(--t-fg-soft);
  font-family: var(--t-font-mono);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}
:root[data-ui="paper"] .topbar-batteries--topbar > summary:hover,
:root[data-ui="paper"] a.topbar-batteries--topbar:hover { background: var(--p-hover); color: var(--t-fg); }
:root[data-ui="paper"] .topbar-batteries--topbar .ph-bold { font-size: 18px; }
:root[data-ui="paper"] .topbar-batteries--topbar .tg-count { background: transparent; padding: 0; color: inherit; }
:root[data-ui="paper"] .topbar-batteries--topbar.is-tone-critical > summary,
:root[data-ui="paper"] a.topbar-batteries--topbar.is-tone-critical { color: var(--t-danger); }
:root[data-ui="paper"] .topbar-batteries--topbar.is-tone-low > summary,
:root[data-ui="paper"] a.topbar-batteries--topbar.is-tone-low { color: var(--t-warn); }
/* The pill morphs into the panel: the panel shares the pill's top-right
   corner and starts clipped to exactly the pill's shape, then the clip
   grows out to the whole panel (and back on close). The pill's icon and
   count stay on top, so they read as the panel's own corner. The base
   script keeps the <details> open in Paper and toggles .is-open. */
:root[data-ui="paper"] .topbar-batteries--topbar > summary { position: relative; z-index: 2; transition: background-color 180ms ease-out, border-color 180ms ease-out; }
:root[data-ui="paper"] .topbar-batteries--topbar.is-open > summary { background: transparent; border-color: transparent; }
:root[data-ui="paper"] .topbar-batteries--topbar .topbar-batteries-popover {
  display: block;
  top: 0;
  right: 0;
  bottom: auto;
  left: auto;
  z-index: 1;
  width: min(300px, var(--pop-room, 300px));
  min-width: 0;
  padding: 0 0 8px;
  border-color: var(--t-border);
  clip-path: inset(0 0 calc(100% - 36px) calc(100% - var(--pill-w, 72px)) round 18px);
  visibility: hidden;
  pointer-events: none;
  transition:
    clip-path 260ms var(--p-ease) 60ms,
    visibility 0s linear 320ms;
}
:root[data-ui="paper"] .topbar-batteries--topbar.is-open .topbar-batteries-popover {
  clip-path: inset(0 round 2px);
  visibility: visible;
  pointer-events: auto;
  transition: clip-path 300ms var(--p-ease), visibility 0s;
}
:root[data-ui="paper"] .topbar-batteries--topbar .topbar-batteries-popover > * { opacity: 0; transition: opacity 90ms ease-out; }
:root[data-ui="paper"] .topbar-batteries--topbar.is-open .topbar-batteries-popover > * { opacity: 1; transition: opacity 180ms ease-out 120ms; }
:root[data-ui="paper"] .topbar-batteries--topbar .topbar-batteries-head {
  display: flex;
  align-items: center;
  height: 36px;
  box-sizing: border-box;
  padding: 0 calc(var(--pill-w, 72px) + 8px) 0 14px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--t-border);
}
@media (prefers-reduced-motion: reduce) {
  :root[data-ui="paper"] .topbar-batteries--topbar .topbar-batteries-popover,
  :root[data-ui="paper"] .topbar-batteries--topbar.is-open .topbar-batteries-popover,
  :root[data-ui="paper"] .topbar-batteries--topbar .topbar-batteries-popover > * { transition: none; }
}
:root[data-ui="paper"] .topbar-batteries-popover .topbar-batteries-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ----- The design switch --------------------------------------------- */

.ui-switch-form { display: contents; }
.ui-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--t-fg-soft);
  background: transparent;
  border: 1px solid var(--t-border);
  border-radius: var(--t-radius-pill);
  padding: 6px 12px;
  cursor: pointer;
  white-space: nowrap;
}
.ui-switch:hover { color: var(--t-fg); background: var(--t-surface-sunk); }
.ui-switch .ph { font-size: 15px; }
.ui-switch-track {
  position: relative;
  width: 34px;
  height: 20px;
  border-radius: 10px;
  background: var(--t-border-strong);
  flex-shrink: 0;
  transition: background-color 180ms ease-out;
}
.ui-switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  border-radius: 7px;
  background: var(--t-surface);
  transition: transform 180ms var(--t-ease-snappy);
}
.ui-switch[aria-checked="true"] .ui-switch-track { background: var(--t-accent); }
.ui-switch[aria-checked="true"] .ui-switch-track::after { transform: translateX(14px); }
/* Drawer / sidebar variant is a full-width row; the classic desktop top
   bar gets the compact pill. */
.ui-switch--nav { display: none; }
.topnav .ui-switch--nav {
  width: 100%;
  justify-content: space-between;
  border: 0;
  border-radius: var(--t-radius);
  padding: 0 var(--t-space-3);
  min-height: 40px;
}
@media (max-width: 900px) {
  .ui-switch--topbar { display: none; }
  .topnav .ui-switch--nav { display: inline-flex; min-height: 44px; }
}
@media (min-width: 901px) {
  :root[data-ui="paper"] .ui-switch--topbar { display: none; }
  :root[data-ui="paper"] .topnav .ui-switch--nav { display: inline-flex; }
}
/* Classic top bar: the pill takes over the right-alignment the theme
   toggle had, unless an earlier right-hand item already claimed it. */
.ui-switch--topbar { margin-left: auto; }
.topbar-discovered--topbar ~ .ui-switch-form .ui-switch--topbar,
.topbar-batteries--topbar ~ .ui-switch-form .ui-switch--topbar,
.topbar-optin ~ .ui-switch-form .ui-switch--topbar,
.topbar-restart-form ~ .ui-switch-form .ui-switch--topbar { margin-left: 4px; }
.ui-switch-form + .theme-toggle--topbar { margin-left: 4px; }

/* ----- Components ---------------------------------------------------- */

:root[data-ui="paper"] .page-head h1,
:root[data-ui="paper"] .card-head h1 { font-weight: 800; letter-spacing: -0.03em; }
:root[data-ui="paper"] .page-head h1 > .ph:first-child { display: none; }  /* titles carry no icon in the mockups */
:root[data-ui="paper"] h2, :root[data-ui="paper"] h3 { letter-spacing: -0.015em; }

:root[data-ui="paper"] .btn { font-weight: 600; border-color: var(--t-border-strong); }
:root[data-ui="paper"] .btn:hover { background: var(--p-hover); }
:root[data-ui="paper"] .btn:active { transform: none; }
/* Primary buttons were a gradient with a gloss highlight; Paper paints
   them flat red, with no lift on hover. */
:root[data-ui="paper"] button.primary,
:root[data-ui="paper"] .btn-primary {
  background: var(--t-accent);
  border-color: var(--t-accent);
  color: var(--t-accent-fg);
  box-shadow: none;
}
:root[data-ui="paper"] button.primary:hover,
:root[data-ui="paper"] .btn-primary:hover {
  background: var(--t-accent-hover);
  border-color: var(--t-accent-hover);
  box-shadow: none;
  transform: none;
}
:root[data-ui="paper"] button.primary:focus-visible,
:root[data-ui="paper"] .btn-primary:focus-visible { box-shadow: none; }
:root[data-ui="paper"] .dow-chip:has(input:checked) { box-shadow: none; }
:root[data-ui="paper"] .rotation-countdown-fill { background: var(--t-accent); }

/* Icon boxes and section icons go monochrome: colour lives in panel
   previews and status, not in decoration. */
:root[data-ui="paper"] .icon-box,
:root[data-ui="paper"] .dx-section-icon,
:root[data-ui="paper"] .dx-section-card .dx-section-icon { background: var(--t-surface-sunk); color: var(--t-fg); }
:root[data-ui="paper"] .tg--teal { background: var(--t-surface-sunk); color: var(--t-fg); }

/* Selected states drew 2px inset rings; Paper keeps hairlines. */
:root[data-ui="paper"] .tile.is-on,
:root[data-ui="paper"] .tile:has(input:checked) {
  background: var(--t-accent-soft);
  color: var(--t-accent-ink);
  box-shadow: inset 0 0 0 1px var(--t-accent);
}
:root[data-ui="paper"] .multiselect-opt.is-dragging { box-shadow: inset 0 0 0 1px var(--t-accent); }
:root[data-ui="paper"] .dxe-pcard.is-selected::after,
:root[data-ui="paper"] .dk-screen.is-live .dk-screen-frame,
:root[data-ui="paper"] .dx-thumb { border-width: 1px; }
:root[data-ui="paper"] .dx-sponsor-card,
:root[data-ui="paper"] .rooms-notice--dep { border-left-width: 1px; }
:root[data-ui="paper"] .topnav .nav-dropdown-panel,
:root[data-ui="paper"] .topbar-batteries-drawer-list li { border-left-width: 1px; }
:root[data-ui="paper"] .tab { border-bottom-width: 1px; }

/* Flashes read as ink notes rather than coloured cards. */
:root[data-ui="paper"] .flash { border-radius: var(--t-radius); }

/* ----- Settings: a second sidebar ---------------------------------- */
/* The settings tab strip (settings_tabs macro, every settings page)
   becomes a full-height column beside the main sidebar on wide screens,
   as in the mockups: a mono "Settings" label, then one quiet row per
   area, the active one shaded (no accent bar). Narrower screens
   keep the horizontal strip. */
@media (min-width: 1100px) {
  :root[data-ui="paper"] { --p-subnav-w: 220px; }
  :root[data-ui="paper"] body.admin:has(.settings-nav) {
    padding-left: calc(var(--p-sidebar-w) + var(--p-subnav-w));
  }
  :root[data-ui="paper"] .settings-nav {
    position: fixed;
    top: 0;
    bottom: 0;
    left: var(--p-sidebar-w);
    width: var(--p-subnav-w);
    box-sizing: border-box;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 32px 12px 24px;
    border-bottom: 0;
    border-right: 1px solid var(--t-border);
    background: var(--p-subnav);
    overflow-x: hidden;
    overflow-y: auto;
    z-index: 5;
  }
  :root[data-ui="paper"] .settings-nav::before {
    content: "Settings";
    display: block;
    padding: 0 12px 14px;
    font-family: var(--t-font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--t-fg-soft);
  }
  :root[data-ui="paper"] .settings-nav .tab {
    display: flex;
    height: 36px;
    padding: 0 12px;
    margin: 0;
    border: 0;
    border-radius: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--t-fg);
    transition: background-color 180ms ease-out;
  }
  :root[data-ui="paper"] .settings-nav .tab .ph { display: none; }
  :root[data-ui="paper"] .settings-nav .tab:hover { background: var(--p-hover); color: var(--t-fg); }
  :root[data-ui="paper"] .settings-nav .tab.is-active {
    background: var(--p-selected);
    color: var(--t-fg);
    font-weight: 600;
  }
  /* The page's entry slide (Motion, below) transforms <main>, and a
     transformed ancestor is the containing block for fixed descendants:
     for its 360ms the column would sit inside the page content, then
     jump to the viewport's left edge when the transform cleared. So
     here the slide moves <main>'s children instead, the column
     excepted, and <main> itself stays put. :where() keeps the rule at
     zero specificity so a child with its own entrance (flashes, the
     save bar) keeps it. */
  :root[data-ui="paper"] body.admin:has(.settings-nav) main.page { animation: none; }
  :where(:root[data-ui="paper"] body.admin:has(.settings-nav) main.page > :not(.settings-nav)) {
    animation: paper-enter 360ms var(--p-ease) backwards;
  }
}
@media (min-width: 1100px) and (prefers-reduced-motion: reduce) {
  :where(:root[data-ui="paper"] body.admin:has(.settings-nav) main.page > :not(.settings-nav)) { animation: none; }
}

/* ----- Raised sheets --------------------------------------------- */
/* Content groups sit on sheets: the surface colour with a 1px edge and
   2px corners, on a ground one step darker than the surface. Rows inside a
   sheet are divided by hairlines. Boxes beyond that are kept only for
   floating layers (menus, popovers, dialogs) and panel previews. */
:root[data-ui="paper"] .card,
:root[data-ui="paper"] .dx-section-card,
:root[data-ui="paper"] .dx-devtable {
  background: var(--t-surface);
  border: 1px solid var(--p-sheet-edge);
  border-radius: 2px;
  padding: 24px 28px;
  box-shadow: none;
}
:root[data-ui="paper"] .dx-section-card + .dx-section-card,
:root[data-ui="paper"] .card + .card { margin-top: 16px; }
/* Side-by-side sections (Stats) align their tops instead. */
:root[data-ui="paper"] .dx-stats-columns > .dx-section-card { margin-top: 0; }
:root[data-ui="paper"] .dx-devtable { padding: 0; }
/* Section heads lose their decorative icon tile; a small red square,
   the one splash of colour, marks every section title instead. */
:root[data-ui="paper"] .dx-section-card .dx-section-icon,
:root[data-ui="paper"] .card-head > .icon-box,
:root[data-ui="paper"] .card-head h2 > .icon-box { display: none; }
:root[data-ui="paper"] .dx-section-title,
:root[data-ui="paper"] .card-head h2 { font-size: 20px; font-weight: 700; letter-spacing: -0.015em; }
:root[data-ui="paper"] .dx-section-title::before,
:root[data-ui="paper"] .card-head h2::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 10px;
  background: var(--p-red);
  vertical-align: middle;
  position: relative;
  top: -2px;
  flex-shrink: 0;
}
:root[data-ui="paper"] .dx-card-footer {
  background: transparent;
  padding: 14px 0 0;
  margin-inline: 0;
  border-top: 1px solid var(--t-border);
}
/* List rows (dashboards, devices, inset rows) are rows inside the sheet. */
:root[data-ui="paper"] .dx-inset-row {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--t-border);
  border-radius: 0;
  padding: 14px 0;
}
:root[data-ui="paper"] .dx-inset-row:hover { background: var(--p-hover); }
/* Dashboards table: the sheet holds the toolbar, an 11px mono head and
   hairline rows; an opened row is a shade down, its figures sunk blocks. */
:root[data-ui="paper"] .dx-dashtable {
  --dx-mono: var(--t-font-mono);
  --dx-border-soft: var(--t-border);
  --dx-teal-soft: var(--t-surface-sunk);
}
:root[data-ui="paper"] .dx-dashtable-head { font-size: 11px; font-weight: 500; color: var(--t-fg-soft); }
:root[data-ui="paper"] .dx-dashrow:hover { background: var(--p-hover); }
:root[data-ui="paper"] .dx-dashrow.is-open { background: var(--t-surface-sunk); }
:root[data-ui="paper"] .dx-dash-name { font-size: 15px; font-weight: 700; }
:root[data-ui="paper"] .dx-dashrow .dx-dash-mono { font-size: 12px; }
:root[data-ui="paper"] .dx-dash-thumb,
:root[data-ui="paper"] .dx-dashquick-preview { border-radius: 2px; }
:root[data-ui="paper"] .dx-dashtable .dx-dashquick { background: var(--t-surface-soft); border-bottom: 1px solid var(--t-border); }
:root[data-ui="paper"] .dx-dashquick-preview { height: 160px; max-height: none; min-height: 0; aspect-ratio: auto; }
:root[data-ui="paper"] .dx-dashtable .dx-qtile {
  background: var(--t-surface-sunk);
  border: 0;
  border-radius: 2px;
  padding: 14px 16px;
  gap: 6px;
}
:root[data-ui="paper"] .dx-dashtable .dx-qtile-label { font-size: 11px; color: var(--t-fg-soft); }
:root[data-ui="paper"] .dx-dashtable .dx-qtile-value { font-size: 22px; letter-spacing: -0.02em; }
:root[data-ui="paper"] .dx-dashtable .dx-qtile-sub { font-family: var(--t-font); font-size: 12px; color: var(--t-fg-soft); }
:root[data-ui="paper"] .dx-dash-chev { color: var(--t-fg); }
/* Display groups: a shaded band with the name in the sheet's ink. */
:root[data-ui="paper"] .dx-dashgroup-head { background: var(--t-surface-soft); border-bottom-color: var(--t-border); }
:root[data-ui="paper"] .dx-dashgroup-head:hover { background: var(--p-hover); }
:root[data-ui="paper"] .dx-dashgroup-name { font-size: 15px; letter-spacing: -0.01em; }
:root[data-ui="paper"] .dx-dashgroup-fold,
:root[data-ui="paper"] .dx-dashgroup-link { color: var(--t-fg); }
:root[data-ui="paper"] .dx-dashgroup-meta { color: var(--t-fg-soft); }
:root[data-ui="paper"] .dx-dashquick-ctls .dx-updates-ctl select { border-color: var(--t-border-strong); }
@container dashtable (max-width: 720px) {
  :root[data-ui="paper"] .dx-dashquick-preview { height: auto; aspect-ratio: 5 / 3; max-height: 220px; }
}
/* Stats: one sheet holding a strip of figures with hairline dividers. */
:root[data-ui="paper"] .dx-stat-tiles {
  background: var(--t-surface);
  border: 1px solid var(--p-sheet-edge);
  border-radius: 2px;
  padding: 16px 12px;
}
:root[data-ui="paper"] .dx-stat-tile {
  background: transparent;
  border: 0;
  border-left: 1px solid var(--t-border);
  border-radius: 0;
  padding: 4px 16px;
}
:root[data-ui="paper"] .dx-stat-tile:first-child { border-left: 0; }
/* Empty states are a quiet sheet; drop zones keep a single dashed hairline. */
:root[data-ui="paper"] .dk-empty {
  background: var(--t-surface);
  border: 1px solid var(--p-sheet-edge);
  border-radius: 2px;
}
:root[data-ui="paper"] .send-box { border-width: 1px; background: var(--t-surface); }

/* Settings fields: label on the left, control on the right, as in the
   mockups (toggle rows already read that way). Wide screens only; below
   that the classic stacked layout stays. */
@media (min-width: 1180px) {
  :root[data-ui="paper"] .dx-section-body > .field:not(.field--slider):not(.field--days) {
    display: grid;
    grid-template-columns: minmax(200px, 300px) minmax(0, 1fr);
    column-gap: 32px;
    align-items: start;
  }
  :root[data-ui="paper"] .dx-section-body > .field:not(.field--slider):not(.field--days) > label {
    grid-column: 1;
    grid-row: 1 / span 4;
    padding-top: 10px;
  }
  :root[data-ui="paper"] .dx-section-body > .field:not(.field--slider):not(.field--days) > :not(label) { grid-column: 2; }
}

/* ----- Corners: 2px everywhere, square in the sidebars --------------- */
/* The dx-* surfaces hard-code their own radii (8-16px) rather than using
   the radius tokens, so cap every element here (2px). Round things stay
   round: switches, radios, status dots, avatars and slider knobs. */
:root[data-ui="paper"] :where(body *:not(svg, svg *):not([class*="dot"]):not([class*="switch"]):not([class*="toggle"]):not([class*="avatar"]):not([class*="knob"]):not([class*="thumb"]):not([role="switch"]):not([role="switch"] *):not(input[type="radio"]):not(input[type="range"])) {
  /* :where keeps this at the specificity of :root[data-ui] alone, so the
     square-cornered rules in this file (sections, sidebar) still win. */
  border-radius: 2px;
}
:root[data-ui="paper"] .topbar,
:root[data-ui="paper"] .topnav { border-radius: 0; }
/* Form controls carry two-class radius rules in the settings sheets. */
:root[data-ui="paper"] :is(input, select, textarea, button):not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([role="switch"]):not([class*="switch"]):not([class*="toggle"]),
:root[data-ui="paper"] .seg,
:root[data-ui="paper"] .dx-status-bar-toggle { border-radius: 2px; }
:root[data-ui="paper"] .topnav a,
:root[data-ui="paper"] .topnav .nav-dropdown-link,
:root[data-ui="paper"] .settings-nav .tab { border-radius: 0; }
:root[data-ui="paper"] .tg,
:root[data-ui="paper"] .tg-count,
:root[data-ui="paper"] [class*="pill"]:not([class*="switch"]) { border-radius: 2px; }

/* ----- Control heights --------------------------------------------- */
/* Paper sets display on controls below; the hidden attribute must still win. */
:root[data-ui="paper"] [hidden] { display: none !important; }
/* One height for every form control so fields line up: 40px standard
   (44px on touch-width screens), 32px for the compact controls that sit
   inside list rows. The classic sheets size these piecemeal (22-47px). */
:root[data-ui="paper"] :is(
  input:is([type="text"], [type="password"], [type="number"], [type="email"], [type="url"],
           [type="search"], [type="tel"], [type="time"], [type="date"], [type="datetime-local"], :not([type])),
  select,
  button.primary, button.ghost, button.button, .btn, .dx-btn, .dx-btn-primary,
  .icon-picker-trigger, .dx-devtb-search, input[type="color"]
):not(.dx-devtb-search input):not([type="hidden"]):not(:is(.dx-inset-row, .dx-updates-ctl) :is(select, button)) {
  box-sizing: border-box;
  height: 40px;
  min-height: 40px;
  padding-block: 0;
  font-size: 14px;
}
:root[data-ui="paper"] :is(button.primary, button.ghost, button.button, .btn, .dx-btn, .dx-btn-primary, .icon-picker-trigger) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* The devices search is a bordered label holding a bare input. */
:root[data-ui="paper"] .dx-devtb-search { display: inline-flex; align-items: center; }
:root[data-ui="paper"] .dx-devtb-search input { height: 100%; min-height: 0; border: 0; background: transparent; }
/* Segmented controls: a 40px track holding the segments. */
:root[data-ui="paper"] :is(.seg, .preview-modes) {
  box-sizing: border-box;
  height: 40px;
  padding: 3px;
  align-items: stretch;
}
:root[data-ui="paper"] :is(.seg-item, .preview-mode) { height: auto; display: inline-flex; align-items: center; }
/* Compact: controls inside list rows. */
:root[data-ui="paper"] :is(.dx-inset-row, .dx-updates-ctl) :is(select, button),
:root[data-ui="paper"] :is(.dx-btn-ghost-sm, .dx-btn-icon-only) {
  box-sizing: border-box;
  height: 32px;
  min-height: 32px;
  padding-block: 0;
  font-size: 13px;
}
:root[data-ui="paper"] .dx-btn-icon-only { width: 32px; padding-inline: 0; }
:root[data-ui="paper"] :is(.dx-btn-ghost-sm, .dx-btn-icon-only) { display: inline-flex; align-items: center; justify-content: center; }
@media (max-width: 900px) {
  :root[data-ui="paper"] :is(
    input:is([type="text"], [type="password"], [type="number"], [type="email"], [type="url"],
             [type="search"], [type="tel"], [type="time"], [type="date"], [type="datetime-local"], :not([type])),
    select,
    button.primary, button.ghost, button.button, .btn, .dx-btn, .dx-btn-primary,
    .icon-picker-trigger, .dx-devtb-search, .seg, .preview-modes
  ):not(.dx-devtb-search input):not([type="hidden"]):not(:is(.dx-inset-row, .dx-updates-ctl) :is(select, button)) {
    height: 44px;
    min-height: 44px;
  }
}

/* ----- Motion -------------------------------------------------------- */

@keyframes paper-enter {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: none; }
}
:root[data-ui="paper"] main.page { animation: paper-enter 360ms var(--p-ease) backwards; }
:root[data-ui="paper"] .card,
:root[data-ui="paper"] .dx-dashboard-card { transition: transform 220ms var(--p-ease), border-color 180ms ease-out; }

@media (prefers-reduced-motion: reduce) {
  :root[data-ui="paper"] main.page { animation: none; }
  :root[data-ui="paper"] .topnav,
  :root[data-ui="paper"] .brand-mark,
  .ui-switch-track,
  .ui-switch-track::after { transition: none; }
}
