/* Vendored from the @fontsource packages: latin subset, woff2 only. */
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:600;font-display:swap;src:url("../fonts/bricolage-grotesque-latin-600-normal.woff2") format("woff2");}
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:700;font-display:swap;src:url("../fonts/bricolage-grotesque-latin-700-normal.woff2") format("woff2");}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:400;font-display:swap;src:url("../fonts/instrument-sans-latin-400-normal.woff2") format("woff2");}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:500;font-display:swap;src:url("../fonts/instrument-sans-latin-500-normal.woff2") format("woff2");}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:600;font-display:swap;src:url("../fonts/instrument-sans-latin-600-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("../fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");}
:root{
--font-display:"Bricolage Grotesque","Trebuchet MS",system-ui,sans-serif;
--font-body:"Instrument Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
--font-mono:"IBM Plex Mono",ui-monospace,"SFMono-Regular",monospace;
}

/* --- tokens/colors.css --- */
:root{
/* --- flash white: the ground. Warmed a touch on cards so nothing is hard #FFF. --- */
--paper-50:#FCFCFB;--paper-100:#F4F4F2;--paper-200:#EFEFEF;--paper-300:#E2E1DE;--paper-400:#CBCAC6;

/* --- dark slate: the ink ramp AND the resting structure colour. --- */
--slate-900:#1E3A44;--slate-800:#284A56;--slate-700:#315762;--slate-550:#426472;--slate-500:#4E7382;--slate-450:#4A6E7D;--slate-400:#5F7F8C;--slate-300:#A8BAC2;--slate-100:#E2EBEF;

/* --- orange: the warm accent. Primary action and "now", nothing else. --- */
--orange-800:#8F3808;--orange-700:#A8430D;--orange-600:#CE5614;--orange-500:#E9631A;--orange-400:#F08A4F;--orange-200:#F9D2B8;--orange-100:#FCEBDF;

/* --- clay: deeper and redder than orange, so "stuck" never reads as "now". --- */
--clay-600:#8C3228;--clay-500:#A64434;--clay-100:#F6E2DD;

/* --- semantic surfaces --- */
--ground:var(--paper-200);
--surface-card:var(--paper-50);
--surface-sunken:var(--paper-300);
--surface-raised:#FFFFFF;
--surface-accent:var(--orange-100);
--surface-inverse:var(--slate-900);
--scrim:rgb(30 58 68 / .48);

/* --- semantic text --- */
--text-body:var(--slate-700);
--text-strong:var(--slate-900);
--text-muted:var(--slate-550);
--text-faint:var(--slate-450);
--text-on-accent:#FFFFFF;
--text-on-inverse:var(--paper-100);
--text-on-done-fill:#FFFFFF;
/* Foregrounds paired with theme-dependent tinted grounds. Never hardcode a
   ramp step on --surface-accent / --accent-quiet: their lightness flips per theme. */
--text-on-accent-surface:var(--orange-700);
--text-on-quiet:var(--orange-700);
/* Accent as TEXT or an icon on the ambient ground (filled buttons use --accent). */
--accent-text:var(--orange-700);
--text-link:var(--orange-700);
--text-link-hover:var(--slate-900);

/* --- semantic lines --- */
--line-hairline:var(--paper-300);
--line-strong:var(--paper-400);
--line-accent:var(--orange-500);
--focus-ring:var(--orange-600);

/* --- interactive --- */
/* Filled surfaces that CARRY TEXT. Deep enough for white at 6:1. */
--accent:var(--orange-700);
--accent-hover:var(--orange-800);
--accent-press:#7A2F05;
--accent-quiet:var(--orange-100);
/* The brand orange at full strength, for fills that carry NO text —
   timer ring, progress fill, chart bars, active tab icon. */
--accent-graphic:var(--orange-500);

/* --- states. done rests into the structure slate; now is the only orange on
       the screen; stuck is clay; later is muted slate. --- */
--state-done:var(--slate-700);--state-done-bg:var(--slate-100);
--state-done-graphic:var(--slate-500); /* @kind color */
--state-now:var(--orange-700);--state-now-bg:var(--orange-100);
--state-now-graphic:var(--orange-500); /* @kind color */
--state-stuck:var(--clay-600);--state-stuck-bg:var(--clay-100);
--state-later:var(--slate-550);--state-later-bg:var(--paper-200);
}
/* Dim theme — evening use and light sensitivity. Slate-based, never black. */
[data-theme="dim"]{
--ground:#16282F;--surface-card:#1E3A44;--surface-sunken:#111F25;--surface-raised:#284A56;
--surface-accent:#3A2A1E;--surface-inverse:var(--paper-100);
--text-body:#DCE6EA;--text-strong:#F2F6F8;--text-muted:#A8BAC2;--text-faint:#96AAB4;
--text-on-accent:#FFFFFF;--text-on-inverse:var(--slate-900);--text-on-done-fill:#0E1B20;
--text-on-accent-surface:#F0A876;--text-on-quiet:#F0A876;--accent-text:#F0A876;
--text-link:#F0A876;--text-link-hover:#F9D2B8;
--line-hairline:#2E5260;--line-strong:#3F6675;--line-accent:var(--orange-400);
--focus-ring:#F08A4F;
--accent:#C24E11;--accent-hover:#D65C18;--accent-press:#A8430D;--accent-quiet:#3A2A1E;--accent-graphic:#F08A4F;
--state-done:#A8C6D2;--state-done-bg:#1B333C;--state-done-graphic:#93B3C1;
--state-now:#F0A876;--state-now-bg:#3A2A1E;--state-now-graphic:#F08A4F;
--state-stuck:#D08A7E;--state-stuck-bg:#33201D;
--state-later:#A8BAC2;--state-later-bg:#1B2E36;
--scrim:rgb(8 16 19 / .64);
}
/* --- tokens/typography.css --- */
:root{
/* sizes — phone-first scale, 1.0 = 16px */
--text-2xs:11px;--text-xs:12px;--text-sm:14px;--text-md:16px;--text-lg:18px;
--text-xl:21px;--text-2xl:26px;--text-3xl:32px;--text-4xl:40px;--text-5xl:52px;--text-6xl:68px;
/* weights */
--weight-regular:400;--weight-medium:500;--weight-semibold:600;--weight-bold:700;
/* leading */
--leading-tight:1.05;--leading-snug:1.2;--leading-normal:1.45;--leading-relaxed:1.6;
/* tracking */
--tracking-display:-0.02em;--tracking-normal:0;--tracking-wide:0.02em;--tracking-caps:0.08em;

/* roles */
--type-display:var(--weight-semibold) var(--text-5xl)/var(--leading-tight) var(--font-display);
--type-title-lg:var(--weight-semibold) var(--text-3xl)/var(--leading-snug) var(--font-display);
--type-title:var(--weight-semibold) var(--text-2xl)/var(--leading-snug) var(--font-display);
--type-subtitle:var(--weight-semibold) var(--text-lg)/var(--leading-snug) var(--font-body);
--type-body:var(--weight-regular) var(--text-md)/var(--leading-normal) var(--font-body);
--type-body-sm:var(--weight-regular) var(--text-sm)/var(--leading-normal) var(--font-body);
--type-label:var(--weight-medium) var(--text-sm)/1.2 var(--font-body);
--type-caption:var(--weight-regular) var(--text-xs)/1.35 var(--font-body);
--type-mono:var(--weight-medium) var(--text-sm)/1.2 var(--font-mono);
--type-timer:var(--weight-medium) var(--text-6xl)/1 var(--font-mono);
}
/* --- tokens/spacing.css --- */
:root{
--space-0:0;--space-1:2px;--space-2:4px;--space-3:8px;--space-4:12px;--space-5:16px;
--space-6:20px;--space-7:24px;--space-8:32px;--space-9:40px;--space-10:56px;--space-11:72px;
/* semantic */
--gutter-screen:20px;      /* phone screen side padding */
--gutter-page:32px;        /* dashboard page padding */
--pad-card:16px;
--pad-card-lg:20px;
--gap-stack:12px;          /* between list rows / stacked cards */
--gap-section:32px;        /* between screen sections */
--tap-min:48px;            /* minimum touch target */
--tap-comfortable:56px;
--rail-width:236px;        /* dashboard sidebar */
--content-max:840px;       /* reading measure on dashboard */
}
/* --- tokens/radius.css --- */
:root{
--radius-xs:6px;--radius-sm:10px;--radius-md:14px;--radius-lg:20px;--radius-xl:28px;--radius-pill:999px;
--radius-card:var(--radius-lg);
--radius-control:var(--radius-md);
--radius-sheet:24px;
--border-hairline:1px;
--border-strong:1.5px;
--focus-width:2px;
--focus-offset:2px;
}
/* --- tokens/elevation.css --- */
:root{
/* Soft, slate-tinted. Never neutral grey, never harsh. */
--shadow-none:none;
--shadow-hairline:0 0 0 1px var(--line-hairline);
--shadow-card:0 1px 2px rgb(30 58 68 / .05), 0 2px 8px rgb(30 58 68 / .05);
--shadow-raised:0 2px 4px rgb(30 58 68 / .07), 0 8px 20px rgb(30 58 68 / .08);
--shadow-sheet:0 -2px 8px rgb(30 58 68 / .06), 0 -18px 44px rgb(30 58 68 / .14);
--shadow-inset:inset 0 1px 0 rgb(255 255 255 / .5);
--shadow-focus:0 0 0 var(--focus-width) var(--surface-card), 0 0 0 calc(var(--focus-width) + 2px) var(--focus-ring);
/* blur is used only for sticky bars over scrolling content */
--blur-bar:saturate(1.1) blur(12px); /* @kind other */
--bar-veil:rgb(239 239 239 / .85);
}
[data-theme="dim"]{
--shadow-card:0 1px 2px rgb(0 0 0 / .3), 0 2px 8px rgb(0 0 0 / .24);
--shadow-raised:0 2px 4px rgb(0 0 0 / .34), 0 8px 20px rgb(0 0 0 / .32);
--shadow-sheet:0 -18px 44px rgb(0 0 0 / .48);
--shadow-inset:inset 0 1px 0 rgb(255 255 255 / .05);
--bar-veil:rgb(22 40 47 / .87);
}
/* --- tokens/motion.css --- */
:root{
/* Calm and short. Nothing bounces, nothing springs, nothing loops in the periphery. */
--dur-instant:80ms;/* @kind other */
--dur-fast:140ms;/* @kind other */
--dur-normal:220ms;/* @kind other */
--dur-slow:320ms;/* @kind other */
--dur-sheet:280ms;/* @kind other */
--ease-standard:cubic-bezier(.2,.6,.2,1);/* @kind other */
--ease-out:cubic-bezier(0,.55,.45,1);/* @kind other */
--ease-in:cubic-bezier(.55,0,1,.45);/* @kind other */
--transition-control:background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard), transform var(--dur-instant) var(--ease-standard);
--press-scale:.985;/* @kind other */
}
/* --- tokens/base.css --- */
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--text-body);font:var(--type-body);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,h4,p{margin:0}
a{color:var(--text-link);text-decoration-color:color-mix(in oklab,var(--text-link) 40%,transparent);text-underline-offset:2px}
a:hover{color:var(--text-link-hover);text-decoration-color:currentColor}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:var(--focus-width) solid var(--focus-ring);outline-offset:var(--focus-offset)}
::selection{background:var(--orange-200);color:var(--slate-900)}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms !important;transition-duration:.01ms !important}}
/* --- app --- */
/* ==========================================================================
   Dupamind — app layer.
   Mobile-first. Phone is the base case; tablet and desk are the overrides.
   Everything visual comes from the ADHD OS design tokens; nothing new is
   invented here beyond layout and interaction state.
   ========================================================================== */

:root {
  --dm-gutter: 20px;          /* phone screen gutter, per the spacing scale */
  --dm-wrap: 620px;           /* the standard content measure */
  --dm-wrap-lg: 680px;        /* the wider one, for lists and canvases */
  --dm-tabbar-h: 62px;        /* bottom bar, safe-area added on top of it */
  --dm-stack: 24px;
}

html {
  /* Safari otherwise inflates type in landscape. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ground);
  /* Stops the whole page rubber-banding away in standalone mode. */
  overscroll-behavior-y: none;
}

a { color: var(--text-link); text-decoration: none; }
a:hover { color: var(--text-link-hover); }

/* Press is carried by border weight and fill timing, never by scale — a
   decision that overrides the design system's own press transform. */
button, [role="button"] { transform: none !important; }

/* No browser tap flash anywhere.
   The default is rgba(51,181,229,.4) — a translucent blue the engine paints
   over whatever was tapped, before any of the app's own press feedback runs.
   It only appears on real touch input, which is why it survives desktop
   testing. The property is inherited, so declaring it once on the root covers
   every element: not just buttons and links but the clickable divs and labels
   the design system's Checkbox, Switch and ListRow are built from.
   This is a different mechanism from :focus-visible, which is untouched — the
   keyboard focus ring below still applies. */
html {
  -webkit-tap-highlight-color: transparent;
}

/* Native controls otherwise take the OS accent, which is also blue: the text
   caret in every field, and any control the design system leaves unstyled.
   The caret is ink, so it takes the ink colour rather than a second orange. */
:root {
  accent-color: var(--accent-graphic);
  caret-color: var(--text-strong);
}

/* Keyboard focus keeps its ring; a mouse click does not leave one behind. */
button:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible) { outline: none !important; }

/* Dim-theme fix: the ramp steps the design system uses for hover states stay
   light unless they are re-pointed inside the dim scope. */
[data-theme="dim"] { --paper-100: #284A56; --paper-50: #1E3A44; --orange-200: #4A3020; }
/* Native select popups are OS-painted: the option list needs its own pair. */
[data-theme="dim"] select option { background-color: #1E3A44; color: #DCE6EA; }
[data-theme="dim"] select option:checked { background-color: #284A56; color: #F2F6F8; }

@keyframes dm-fade-in { from { opacity: 0.55; } to { opacity: 1; } }

/* ==========================================================================
   Shell
   ========================================================================== */

.dm-app {
  min-height: 100vh;
  min-height: 100dvh;   /* iOS: 100vh is the tall viewport and clips */
  display: flex;
  flex-direction: column;
  background: var(--ground);
  color: var(--text-body);
  font: var(--type-body);
}

.dm-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* --- top bar host: the app bar on phone, the timer bar on every size --- */
.dm-topbar {
  position: sticky;
  top: 0;
  z-index: 15;
  padding-top: env(safe-area-inset-top);
  background: var(--bar-veil);
  backdrop-filter: var(--blur-bar);
  -webkit-backdrop-filter: var(--blur-bar);
}

/* The depleting session bar. Full-bleed, no digits. On phone it rides the
   bottom edge of the app bar, so Safari's collapsing address bar can never
   sit on top of it. */
.dm-timerbar {
  height: 6px;
  background: var(--surface-sunken);
  overflow: hidden;
  transition: height var(--dur-fast) var(--ease-standard);
}
.dm-timerbar[data-final="true"] { height: 9px; }
.dm-timerbar-fill {
  height: 100%;
  background: var(--accent-graphic);
}

/* --- screens --- */
.dm-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--dm-stack);
  padding: 20px var(--dm-gutter) calc(var(--dm-tabbar-h) + 32px + env(safe-area-inset-bottom));
}
.dm-screen--full {
  /* splash and gate: no chrome, so they own the whole viewport */
  min-height: 100vh;
  min-height: 100dvh;
  justify-content: center;
  padding: calc(32px + env(safe-area-inset-top)) var(--dm-gutter)
           calc(32px + env(safe-area-inset-bottom));
}

.dm-wrap { width: 100%; max-width: var(--dm-wrap); }
.dm-wrap-lg { width: 100%; max-width: var(--dm-wrap-lg); }
.dm-wrap-sm { width: 100%; max-width: 420px; }

.dm-stack { display: flex; flex-direction: column; }
.dm-row { display: flex; align-items: center; }
.dm-spacer { flex: 1; }

/* A screen's uppercase eyebrow repeats the app bar title on phone, so it is
   only shown once the desk rail takes over the naming job. */
.dm-eyebrow {
  font: var(--type-caption);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-faint);
  display: none;
}
.dm-eyebrow-row { display: none; }

/* A screen header whose control sits beside it on a wide screen and stacks
   underneath on a phone. */
.dm-head {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  width: 100%;
}
.dm-head-control { width: 100%; }

.dm-title { font: var(--type-title); letter-spacing: var(--tracking-display); color: var(--text-strong); }
.dm-title-lg { font: var(--type-title); letter-spacing: var(--tracking-display); color: var(--text-strong); text-wrap: pretty; }
.dm-body { font: var(--type-body); color: var(--text-muted); text-wrap: pretty; }
.dm-body-sm { font: var(--type-body-sm); color: var(--text-muted); text-wrap: pretty; }
.dm-label { font: var(--type-label); color: var(--text-body); }
.dm-caption { font: var(--type-caption); color: var(--text-faint); }
.dm-mono { font: var(--type-mono); color: var(--text-faint); }

/* Action clusters must wrap rather than overflow a 320px screen. */
.dm-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dm-actions--tight { gap: 8px; }
/* The three session controls share the width evenly rather than wrapping and
   leaving Stop stranded on a line of its own. */
.dm-actions--session { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dm-actions--session > * { width: 100%; }

/* ==========================================================================
   Grids
   ========================================================================== */

/* Energy and duration tiles stay three-across at every width: the whole
   promise of the screen is two taps without scrolling. */
.dm-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dm-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
/* Rooms reflow by available width instead of a fixed column count. */
.dm-grid-rooms { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
.dm-grid-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.dm-grid-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.dm-grid-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.dm-grid-pops { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; }
.dm-grid-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.dm-grid-mood { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dm-grid-relocate { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }

/* ==========================================================================
   Hand-rolled controls
   Hover is gated behind a real pointer so a tap never leaves a stuck state.
   Press answers with border weight and fill, never scale.
   ========================================================================== */

.dm-tile,
.dm-choice,
.dm-mood,
.dm-tilecard,
.dm-pop,
.dm-swatch,
.dm-rail-item {
  cursor: pointer;
  font: var(--type-label);
  transition: border-color var(--dur-fast) cubic-bezier(.2, .8, .3, 1),
              background-color var(--dur-normal) var(--ease-standard),
              box-shadow var(--dur-normal) var(--ease-standard);
}

.dm-tile:focus-visible,
.dm-choice:focus-visible,
.dm-mood:focus-visible,
.dm-tilecard:focus-visible,
.dm-pop:focus-visible,
.dm-swatch:focus-visible,
.dm-rail-item:focus-visible,
.dm-fill:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* --- tiles: energy, duration, rooms, relocate targets, profile chips --- */
.dm-tile {
  border: var(--border-strong) solid var(--line-hairline);
  background: var(--surface-card);
  color: var(--text-body);
  border-radius: var(--radius-md);
  min-height: var(--tap-min);
  padding: 8px 12px;
}
.dm-tile--lg { min-height: 76px; border-radius: var(--radius-lg); font: var(--type-subtitle); box-shadow: var(--shadow-card); }
.dm-tile--md { min-height: 64px; border-radius: var(--radius-lg); font: var(--type-subtitle); box-shadow: var(--shadow-card); }
.dm-tile--pill { border-radius: var(--radius-pill); padding: 0 20px; }
@media (hover: hover) {
  .dm-tile:hover { border-color: var(--line-strong); }
}
.dm-tile:active {
  border-width: 2.5px;
  border-color: var(--line-accent);
  background: var(--surface-accent);
  color: var(--text-on-accent-surface);
}
.dm-tile[aria-pressed="true"] {
  border-width: 2.5px;
  border-color: var(--line-accent);
  background: var(--surface-accent);
  color: var(--text-on-accent-surface);
}

/* --- the four doom-pile choices: equal weight, icon over label --- */
.dm-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  min-height: 112px;
  padding: 16px;
  border: var(--border-strong) solid var(--line-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  color: var(--text-body);
  box-shadow: var(--shadow-card);
  font: var(--type-subtitle);
  text-align: left;
}
@media (hover: hover) {
  .dm-choice:hover { border-color: var(--line-strong); box-shadow: var(--shadow-raised); }
}
.dm-choice:active {
  border-width: 2.5px;
  border-color: var(--line-accent);
  background: var(--surface-accent);
  color: var(--text-on-accent-surface);
}

/* --- journal mood faces --- */
.dm-mood {
  min-height: 64px;
  border: var(--border-hairline) solid var(--line-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  color: var(--text-body);
  display: flex;
  align-items: center;
  justify-content: center;
}
@media (hover: hover) {
  .dm-mood:hover { border-color: var(--line-strong); }
}
.dm-mood:active { border-width: 2.5px; border-color: var(--line-accent); }
.dm-mood[aria-pressed="true"] { background: var(--surface-accent); border-color: var(--line-accent); }

/* --- memory tiles --- */
.dm-tilecard {
  aspect-ratio: 1;
  border: var(--border-hairline) solid var(--line-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  color: var(--text-body);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
@media (hover: hover) {
  .dm-tilecard:hover { border-color: var(--line-strong); }
}
.dm-tilecard:active { border-width: 2.5px; border-color: var(--line-accent); }
.dm-tilecard--shown { background: var(--surface-card); border-color: var(--line-strong); }
.dm-tilecard--done {
  aspect-ratio: 1;
  border: var(--border-hairline) solid transparent;
  border-radius: var(--radius-md);
  background: var(--state-done-bg);
  color: var(--state-done);
  display: flex;
  align-items: center;
  justify-content: center;
}
.dm-tilecard svg { width: 68%; height: 68%; }

/* --- bubble pop --- */
.dm-pop {
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  border: var(--border-hairline) solid var(--line-hairline);
  background: var(--surface-sunken);
  box-shadow: var(--shadow-inset);
  padding: 0;
}
@media (hover: hover) {
  .dm-pop:hover { border-color: var(--line-strong); }
}
.dm-pop:active { border-width: 2.5px; background: var(--surface-raised); }
.dm-pop--down {
  border: 3px solid var(--state-done-graphic);
  background: var(--state-done-bg);
  box-shadow: none;
}

/* --- colouring palette --- */
.dm-swatch {
  width: var(--tap-min);
  height: var(--tap-min);
  border-radius: var(--radius-pill);
  border: var(--border-hairline) solid var(--line-strong);
  padding: 0;
}
@media (hover: hover) {
  .dm-swatch:hover { border-color: var(--text-strong); }
}
.dm-swatch:active { border-width: 2px; border-color: var(--text-strong); }
.dm-swatch[aria-pressed="true"] { border-width: 2px; border-color: var(--text-strong); }
.dm-palette { display: flex; gap: 8px; flex-wrap: wrap; }

/* The design system's Slider paints its track with a background gradient, but
   a thumb lives in a pseudo-element, which inline styles cannot reach — so it
   falls back to the OS default: system blue, and a puck that is hard to catch
   with a thumb. Both are fixed here, in the system's own tokens. Orange with
   no text on it is exactly what --accent-graphic is for. */
input[type="range"] { -webkit-appearance: none; appearance: none; }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--accent-graphic);
  border: 2px solid var(--surface-card);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--accent-graphic);
  border: 2px solid var(--surface-card);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
input[type="range"]:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* ==========================================================================
   Splash
   One slow breath, so the screen reads as waiting rather than stuck. This is
   a deliberate exception to the system's "nothing pulses or loops" rule: that
   rule exists so nothing moves in the periphery while a person is trying to
   focus, and on the splash there is no task to focus on and nothing else on
   screen. Scale and opacity only — no glow, no gradient, no bounce, and one
   shared rhythm so it reads as a single breath rather than two animations.
   Both stop dead under reduce-motion, via .dm-still and the media query.
   ========================================================================== */

.dm-splash { cursor: pointer; gap: 32px; }
.dm-splash:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: -6px;
}
.dm-splash-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
.dm-splash-mark {
  width: 88px;
  height: 88px;
  display: block;
  border-radius: var(--radius-lg);
  animation: dm-breathe 3800ms var(--ease-standard) infinite alternate;
}
.dm-splash-word {
  font: var(--type-title);
  letter-spacing: -0.03em;
  color: var(--text-strong);
}
.dm-splash-hint {
  font: var(--type-label);
  color: var(--text-faint);
  opacity: 1;
  animation: dm-breathe-hint 3800ms var(--ease-standard) infinite alternate;
}
/* The press answer is a small settle on the mark, not a full-screen fill. */
.dm-splash:active .dm-splash-mark { opacity: 0.82; }

/* The placeholder tile is dark slate, which sits very close to the dim
   ground, so its edge needs a hairline there. Structure, not a glow. */
[data-theme="dim"] .dm-splash-mark { box-shadow: 0 0 0 1px var(--line-hairline); }

@keyframes dm-breathe {
  from { transform: scale(1); }
  to { transform: scale(1.03); }
}
@keyframes dm-breathe-hint {
  from { opacity: 0.5; }
  to { opacity: 1; }
}

/* Colouring regions are real controls: tappable, keyboard reachable. */
.dm-fill { cursor: pointer; }
.dm-canvas { width: 100%; display: block; }

/* ==========================================================================
   Phone chrome: app bar + bottom bar + more sheet
   ========================================================================== */

.dm-tabbar-host {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 16;
}
/* Six destinations at 320px is 50px a slot: above the tap minimum in width
   terms once the row's own height is counted, and the label must not wrap. */
.dm-tabbar-host nav > button > span { white-space: nowrap; }
.dm-tabbar-host nav > button { min-width: 0; }

/* The secondary panel is a bottom sheet on a phone — it opens from the bar
   it was tapped on — and a left drawer on the desk. */
.dm-more-scrim { position: absolute; inset: 0; background: var(--scrim); }
.dm-more-host { position: fixed; inset: 0; z-index: 20; }
.dm-more-panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 82vh;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--surface-card);
  box-shadow: var(--shadow-sheet);
  border-top-left-radius: var(--radius-sheet);
  border-top-right-radius: var(--radius-sheet);
  padding: 20px var(--dm-gutter) calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Sheets: install prompt, relocate. */
.dm-sheet-host {
  position: fixed;
  inset: 0;
  z-index: 25;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.dm-sheet {
  position: relative;
  width: 100%;
  max-width: 520px;
  background: var(--surface-card);
  border-top-left-radius: var(--radius-sheet);
  border-top-right-radius: var(--radius-sheet);
  box-shadow: var(--shadow-sheet);
  padding: 20px var(--dm-gutter) calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-height: 88vh;
  overflow: auto;
}
/* The install prompt is flat by decision: a top hairline, no shadow. */
.dm-install-host {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 22;
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.dm-install {
  pointer-events: auto;
  width: 100%;
  max-width: 560px;
  background: var(--surface-card);
  border-top: var(--border-hairline) solid var(--line-hairline);
  border-top-left-radius: var(--radius-xl);
  border-top-right-radius: var(--radius-xl);
  padding: 20px var(--dm-gutter) calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-height: 76vh;
  overflow: auto;
}
.dm-install-step { display: flex; align-items: flex-start; gap: 12px; }
.dm-install-n {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font: var(--type-mono);
}
.dm-install-glyph {
  flex: none;
  width: 32px;
  height: 32px;
  border: var(--border-hairline) solid var(--line-hairline);
  border-radius: var(--radius-sm);
  color: var(--text-body);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The toast has to clear the bottom bar and the home indicator. */
.dm-toast-host {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--dm-tabbar-h) + 16px + env(safe-area-inset-bottom));
  z-index: 30;
  width: max-content;
  max-width: calc(100vw - 32px);
}

/* ==========================================================================
   The desk rail — hidden until there is a pointer and the width for it
   ========================================================================== */

.dm-rail { display: none; }

.dm-rail-item {
  position: relative;
  height: var(--tap-min);
  width: 100%;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  text-align: left;
  white-space: nowrap;
}
@media (hover: hover) {
  .dm-rail-item:hover { background: var(--surface-raised); color: var(--text-body); }
}
.dm-rail-item:active { background: var(--surface-accent); color: var(--text-on-accent-surface); }
.dm-rail-item[aria-current="page"] {
  background: var(--surface-accent);
  color: var(--text-on-accent-surface);
}
.dm-rail-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 3px;
  border-radius: var(--radius-pill);
  background: var(--accent-graphic);
}

/* --- journal composer --- */
.dm-journal-sheet {
  border: var(--border-hairline) solid var(--line-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.dm-ruled {
  width: 100%;
  box-sizing: border-box;
  border: none;
  outline: none;
  resize: vertical;
  min-height: 220px;
  padding: 15px var(--dm-gutter) 20px;
  line-height: 32px;
  font: var(--type-body);
  color: var(--text-body);
  background-color: var(--surface-card);
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0px, transparent 31px,
    var(--line-hairline) 31px, var(--line-hairline) 32px
  );
  background-position: 0 16px;
}

/* --- calendar --- */
.dm-day {
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font: var(--type-mono);
  color: var(--text-faint);
}
.dm-day--active { background: var(--state-done-bg); color: var(--state-done); }

.dm-plan-subs { padding-left: 20px; }

/* Wide content never pushes the page sideways. */
.dm-scroll-x { overflow-x: auto; }

/* ==========================================================================
   Tablet — 768px and up
   ========================================================================== */

@media (min-width: 768px) {
  :root { --dm-gutter: 32px; --dm-stack: 32px; --dm-tabbar-h: 64px; }

  .dm-screen { padding: 40px var(--dm-gutter) calc(var(--dm-tabbar-h) + 40px + env(safe-area-inset-bottom)); }
  .dm-screen--tight { gap: 24px; }

  .dm-head { flex-direction: row; align-items: center; justify-content: space-between; gap: 16px; }
  .dm-head-control { width: 220px; flex: none; }

  .dm-grid-3 { gap: 12px; }
  .dm-grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dm-grid-choices { gap: 16px; }
  .dm-grid-tiles { gap: 12px; }
  .dm-grid-pops { gap: 12px; }
  .dm-grid-cal { gap: 8px; }
  .dm-grid-mood { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .dm-grid-relocate { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .dm-actions--session { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .dm-actions--session > * { width: auto; }

  .dm-tile--lg { min-height: 88px; }
  .dm-tile--md { min-height: 72px; }
  .dm-choice { min-height: 132px; padding: 20px; gap: 28px; }
  .dm-title { font: var(--type-title); }
  .dm-title-lg { font: var(--type-title-lg); }
  .dm-ruled { min-height: 260px; }
  .dm-plan-subs { padding-left: 32px; }

  .dm-more-panel { max-height: 70vh; }
}

/* ==========================================================================
   Desk — 1024px and up. The approved laptop layout, unchanged.
   ========================================================================== */

@media (min-width: 1024px) {
  :root { --dm-gutter: 40px; }

  .dm-app { flex-direction: row; }

  .dm-rail {
    display: flex;
    flex: none;
    flex-direction: column;
    gap: 4px;
    width: 76px;
    padding: 20px 12px;
    border-right: var(--border-hairline) solid var(--line-hairline);
    background: var(--surface-card);
    position: sticky;
    top: 0;
    height: 100vh;
    box-sizing: border-box;
    overflow: hidden;
    transition: width var(--dur-normal) var(--ease-standard);
  }
  .dm-rail[data-open="true"] { width: 236px; }
  .dm-rail[data-still="true"] { transition: none; }

  /* The app bar's naming job goes back to the rail; the timer bar returns to
     the viewport's top edge, full-bleed across the whole window. */
  .dm-appbar { display: none; }
  .dm-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    padding-top: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    pointer-events: none;
  }
  .dm-tabbar-host { display: none; }

  .dm-eyebrow { display: block; }
  .dm-eyebrow-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; }

  .dm-screen { padding: 56px var(--dm-gutter) 72px; }
  .dm-toast-host { bottom: 32px; }

  /* The secondary panel becomes the desk drawer again. */
  .dm-more-panel {
    right: auto;
    top: 0;
    bottom: 0;
    width: 320px;
    max-height: none;
    border-radius: 0;
    box-shadow: var(--shadow-raised);
    padding: 24px 20px;
    gap: 24px;
  }

  .dm-sheet-host { align-items: flex-end; }
  .dm-sheet { padding: 24px 20px; }
  .dm-install { padding: 24px 20px; }
}

/* ==========================================================================
   Reduce motion — either the system setting or the app's own switch
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
.dm-still, .dm-still * { animation: none !important; transition: none !important; }
