/* Plans — paper and ink.
   The look is a notebook, not a dashboard: warm paper, hairline rules,
   a serif for anything that speaks. Colour is rationed — it means something
   when it appears (a deadline missed, a project, a streak alive). */

:root {
    color-scheme: light dark;

    /* Paper. Every other theme is data in app.js (THEMES), written onto
       <html> as inline variables by applyPrefs(); these are what "Match my
       system" shows by day, and what paints before any script has run. */
    /* Sand & clay, the logo's colours (Paper is still a theme of its own). */
    --bg:          #faf7f2;
    --surface:     #fffdf9;
    --surface-2:   #efe8dd;
    --rule:        #e6dccd;
    --rule-soft:   #ece4d8;

    /* Espresso ink */
    --text:        #3b2a22;
    --text-dim:    #76594a;
    --text-faint:  #7a695e;

    /* Rationed colour. The accent comes in a light-paper (-l) and a
       dark-paper (-d) variant; the theme wears whichever suits it. Pine
       here, replaced by whatever accent is chosen. */
    --accent-l:      #76594a;
    --accent-soft-l: #efe6df;
    --accent-d:      #e8d5be;
    --accent-soft-d: #45362f;
    --accent:      var(--accent-l);
    --accent-soft: var(--accent-soft-l);
    --warn:        #9f6348;   /* clay — late, and streaks */
    --warn-soft:   #f3e6dc;
    --danger:      #a3452e;   /* iron oxide */
    --good:        #6c7552;

    /* Shape and type, also set from the Style tab. */
    --radius:      4px;
    --radius-sm:   3px;
    --tap:         44px;
    --base-size:   16px;

    --serif: Newsreader, "Iowan Old Style", "Palatino Linotype", Palatino,
             Georgia, "Times New Roman", serif;
    --sans:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* "Match my system" at night: Ink. An explicit theme stamps data-theme and
   brings its own palette, so this only applies with none. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        /* Night clay */
        --bg: #2e2420; --surface: #3a2d27; --surface-2: #45362f;
        --rule: #4f3f37; --rule-soft: #443630;
        --text: #f3e6d4; --text-dim: #c9a58a; --text-faint: #ad9988;
        --warn: #d79a74; --warn-soft: #43322a; --danger: #e0806a; --good: #a9b88a;
        --accent: var(--accent-d); --accent-soft: var(--accent-soft-d);
        /* Widget accents and badge lettering that read on dark paper. */
        --w-pine: #7da893; --w-slate: #86a6c4; --w-plum: #b294b8; --w-moss: #a3b174;
        --on-danger: #1a1a1a;
    }
}
/* Hints in empty fields, in the theme's faintest text (kept readable by every theme), not the browser's grey. */
::placeholder { color: var(--text-faint); opacity: 1; }

/* ---------- Density ---------- */
:root[data-density="compact"] {
    --tap: 38px;
}
:root[data-density="compact"] .task,
:root[data-density="compact"] .habit,
:root[data-density="compact"] .shared-row,
:root[data-density="compact"] .rule { padding-top: 7px; padding-bottom: 7px; }
:root[data-density="compact"] .panel { padding: 9px 11px 11px; }
:root[data-density="compact"] .board { --gap: 11px; }
:root[data-density="compact"] body { font-size: calc(var(--base-size) - 1px); }
:root[data-density="compact"] .section { margin-top: 22px; }

/* ---------- Typeface ---------- */
/* Turning the serif off gives everything the UI sans — plainer, more like a
   tool than a notebook. */
:root[data-serif="off"] {
    --serif: var(--sans);
}
:root[data-serif="off"] .greeting,
:root[data-serif="off"] .panel-title,
:root[data-serif="off"] .section-title { font-weight: 600; letter-spacing: -.01em; }
:root[data-serif="off"] .datestamp,
:root[data-serif="off"] .task-meta,
:root[data-serif="off"] .habit-sub,
:root[data-serif="off"] .rule-sub,
:root[data-serif="off"] .day-count,
:root[data-serif="off"] .panel-note,
:root[data-serif="off"] .empty { font-style: normal; }

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--text);
    font: var(--base-size)/1.55 var(--sans);
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
}

body { padding-bottom: env(safe-area-inset-bottom, 0px); }
/* With the on-screen keyboard up (--kb, set by app.js), room to scroll the
   bottom of the page above it. */
body.keyboard-open { padding-bottom: calc(var(--kb, 0px) + 24px); }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
[hidden] { display: none !important; }

/* ---------- Layout ---------- */

.shell { max-width: 1680px; margin: 0 auto; padding: 0 24px 104px; }
/* A long word, link or name breaks where it must rather than pushing past
   the edge (it also lets the boxes holding it shrink to the screen). */
main, .sheet, .nav-more { overflow-wrap: anywhere; }

/* Focused views (week, settings, a task list) still want a reading measure —
   only the board spreads out. */
.shell.narrow-view > section { max-width: 820px; margin: 0 auto; }

.topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    background: color-mix(in srgb, var(--bg) 92%, transparent);
    backdrop-filter: blur(10px);
    /* Full-width bar: no horizontal padding or negative margin of its own —
       the .shell inside it supplies the gutters, and a negative margin here
       pushed the header past the viewport edge on a phone. */
    padding: calc(env(safe-area-inset-top, 0px) + 18px) 0 10px;
    border-bottom: 1px solid transparent;
    transition: border-color .2s;
}
.topbar.scrolled { border-bottom-color: var(--rule); }

.topbar-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }

.greeting {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.7rem;
    font-weight: 400;
    letter-spacing: -.01em;
    line-height: 1.15;
}
.datestamp {
    font-family: var(--serif);
    font-style: italic;
    font-size: .92rem;
    color: var(--text-dim);
    white-space: nowrap;
}

/* Tabs: underlined, the way a printed index is — not pills in a tray. */
.tabs {
    display: flex;
    gap: 20px;
    margin-top: 14px;
    border-bottom: 1px solid var(--rule);
    /* Seven tabs do not fit a phone: the row scrolls sideways instead of
       wrapping, and the open tab is scrolled into view (showTab). */
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
    border: 0;
    background: none;
    color: var(--text-dim);
    padding: 7px 0 9px;
    font-size: .9rem;
    font-weight: 500;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color .15s, border-color .15s;
}
.tabs button:hover { color: var(--text); }
.tabs button[aria-selected="true"] {
    color: var(--text);
    border-bottom-color: var(--accent);
}
.tabs .pip {
    display: inline-block;
    margin-left: 5px;
    font-size: .75rem;
    font-weight: 500;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}
.tabs button[aria-selected="true"] .pip { color: var(--accent); }

/* ---------- Sections ---------- */

.section { margin-top: 30px; }
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 6px;
    padding-bottom: 5px;
    border-bottom: 1px solid var(--rule-soft);
}
.section-title {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.02rem;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text);
}
.section-title.warn { color: var(--warn); }

.empty {
    padding: 16px 2px;
    color: var(--text-faint);
    font-size: .9rem;
    font-family: var(--serif);
    font-style: italic;
}

/* The "card" is now just a grouped list on the page itself. */
.card { background: none; border: 0; border-radius: 0; box-shadow: none; }

/* Forms and sheets still need a surface to sit on. */
form.card, .card.panel {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
}

/* ---------- Tasks ---------- */

.task {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 11px 2px;
    border-bottom: 1px solid var(--rule-soft);
}
.task:last-child { border-bottom: 0; }

.check {
    flex: 0 0 auto;
    width: 19px;
    height: 19px;
    margin-top: 3px;
    border: 1.5px solid var(--text-faint);
    border-radius: 50%;
    background: transparent;
    padding: 0;
    display: grid;
    place-items: center;
    transition: border-color .15s, background .15s;
}
.check:hover { border-color: var(--accent); }
.check svg { width: 11px; height: 11px; opacity: 0; transition: opacity .15s; }
.task.done .check { background: var(--good); border-color: var(--good); }
.task.done .check svg { opacity: 1; stroke: var(--bg); }

.task-body { flex: 1; min-width: 0; }
.task-title {
    display: block;
    width: 100%;
    border: 0;
    background: none;
    padding: 0;
    text-align: left;
    line-height: 1.45;
    word-wrap: break-word;
}
.task.done .task-title { color: var(--text-faint); text-decoration: line-through; }

/* Metadata reads as a margin note, not a row of badges. */
.task-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 3px;
    font-size: .78rem;
    color: var(--text-dim);
    font-family: var(--serif);
    font-style: italic;
}
.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 0;
    border-radius: 0;
    background: none;
    white-space: nowrap;
}
.chip.late { color: var(--warn); font-style: normal; font-weight: 600; }
.chip.dot::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.prio-3 { color: var(--danger); font-style: normal; font-weight: 600; }
.prio-2 { color: var(--warn); font-style: normal; }

.task-actions { display: flex; gap: 1px; flex: 0 0 auto; opacity: 0; transition: opacity .15s; }
.task:hover .task-actions, .task:focus-within .task-actions { opacity: 1; }
@media (hover: none) { .task-actions { opacity: 1; } }
/* On touch screens a row keeps to its tick and title, with a quiet ⋯ that
   opens its actions (and an unset length) for that row alone. */
.more-acts { display: none; }
@media (hover: none) {
    .more-acts { display: inline-flex; color: var(--text-faint); }
    .task.acts-open .more-acts { color: var(--accent); }
    .task:not(.acts-open) .task-actions > :not(.more-acts) { display: none; }
    .task:not(.acts-open) .chip.est.unset { display: none; }
    .task:not(.acts-open) .task-meta:not(:has(> :not(.est.unset))) { display: none; }
}
/* Likewise, hover-only actions overlay the row instead of reserving width
   that makes every title wrap early. */
@media (hover: hover) {
    .task { position: relative; }
    .task-actions {
        position: absolute;
        right: 0;
        top: 8px;
        background: var(--under, var(--bg));
        border-radius: var(--radius-sm);
        box-shadow: -10px 0 8px -2px var(--under, var(--bg));
        pointer-events: none;
    }
    .task:hover .task-actions, .task:focus-within .task-actions { pointer-events: auto; }
}

.icon-btn {
    border: 0;
    background: none;
    color: var(--text-faint);
    padding: 5px;
    border-radius: var(--radius-sm);
    line-height: 0;
    transition: background .15s, color .15s;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 16px; height: 16px; }

/* ---------- The day's line ---------- */

.dayline {
    margin-top: 26px;
    padding-top: 14px;
    border-top: 1px solid var(--rule-soft);
    font-family: var(--serif);
    font-size: 1rem;
    color: var(--text-dim);
    line-height: 1.6;
}
.dayline b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------- Quick capture ---------- */

.capture {
    position: fixed;
    left: 0; right: 0; bottom: var(--kb, 0px);
    z-index: 30;
    padding: 11px 20px calc(11px + env(safe-area-inset-bottom, 0px));
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--rule);
}
.capture-inner { max-width: 1680px; margin: 0 auto; display: flex; gap: 8px; }
.capture input {
    flex: 1;
    min-width: 0;
    height: var(--tap);
    padding: 0 14px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    outline: none;
    transition: border-color .15s;
}
.capture input::placeholder { font-family: var(--serif); font-style: italic; color: var(--text-faint); }
.capture input:focus { border-color: var(--accent); }

.btn {
    height: var(--tap);
    padding: 0 18px;
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    background: var(--fill, var(--accent));
    color: var(--on-fill, var(--surface));
    font-size: .92rem;
    font-weight: 500;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: filter .15s;
}
.btn:hover { filter: brightness(1.1); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
.btn.ghost {
    background: var(--surface);
    color: var(--text);
    border-color: var(--rule);
}
.btn.ghost:hover { background: var(--surface-2); filter: none; }
.btn.small { height: 32px; padding: 0 11px; font-size: .84rem; }

/* ---------- Habits ---------- */

.habit {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 11px 2px;
    border-bottom: 1px solid var(--rule-soft);
}
.habit:last-child { border-bottom: 0; }

.habit-tick {
    flex: 0 0 auto;
    width: 26px; height: 26px;
    border-radius: var(--radius-sm);
    border: 1.5px solid var(--text-faint);
    background: transparent;
    display: grid;
    place-items: center;
    padding: 0;
    transition: transform .12s, background .15s, border-color .15s;
}
.habit-tick:hover { border-color: var(--accent); }
.habit-tick:active { transform: scale(.9); }
.habit-tick svg { width: 14px; height: 14px; opacity: 0; stroke: #f7f4ee; }
.habit-tick[aria-pressed="true"] svg { opacity: 1; }
.habit-tick.off { opacity: .4; }

.habit-body { flex: 1; min-width: 0; }
.habit-name { font-weight: 500; }
/* Habit and repeating names open their editor: text that is quietly a button. */
.habit-name, .rule-name {
    display: block;
    border: 0;
    background: none;
    padding: 0;
    text-align: left;
    line-height: 1.45;
    overflow-wrap: anywhere;
}
.habit-sub {
    font-size: .8rem;
    color: var(--text-dim);
    margin-top: 1px;
    font-family: var(--serif);
    font-style: italic;
}
.flame { color: var(--warn); font-style: normal; font-weight: 600; }

.grid28 { display: flex; gap: 3px; margin-top: 7px; }
.grid28 i {
    width: 8px; height: 8px;
    border-radius: 1px;
    background: var(--surface-2);
    display: block;
}
.grid28 i.on { background: var(--good); }
.grid28 i.skip { opacity: .3; }

/* ---------- Momentum ---------- */

.momentum { display: flex; align-items: flex-end; gap: 5px; height: 40px; padding: 12px 0 2px; }
.momentum span {
    flex: 1;
    background: var(--text-faint);
    border-radius: 1px;
    min-height: 2px;
    opacity: .35;
}
.momentum span.has { opacity: 1; background: var(--fill, var(--accent)); }
.momentum span.today { background: var(--warn); }

/* ---------- Forms / login ---------- */

.centered { min-height: 100dvh; display: grid; place-items: center; padding: 24px 20px; }

.field { margin-bottom: 14px; }
.field label {
    display: block;
    font-size: .8rem;
    font-weight: 500;
    color: var(--text-dim);
    margin-bottom: 5px;
}
.field input, .field select {
    width: 100%;
    height: var(--tap);
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    outline: none;
    transition: border-color .15s;
}
.field input:focus, .field select:focus { border-color: var(--accent); }

.notice {
    padding: 11px 13px;
    border-radius: var(--radius);
    background: var(--warn-soft);
    color: var(--text);
    font-size: .875rem;
    margin-bottom: 14px;
    border-left: 3px solid var(--warn);
}
.notice.error { background: color-mix(in srgb, var(--danger) 10%, transparent); border-left-color: var(--danger); }

/* ---------- Toast ---------- */

.toast {
    position: fixed;
    left: 50%;
    bottom: calc(78px + env(safe-area-inset-bottom, 0px));
    transform: translate(-50%, 10px);
    z-index: 60;
    background: var(--text);
    color: var(--bg);
    padding: 8px 15px;
    border-radius: var(--radius);
    font-size: .85rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s, transform .18s;
    max-width: calc(100vw - 40px);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.show.has-action { pointer-events: auto; }
.toast button {
    margin-left: 10px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ---------- Settings ---------- */

.setting-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 12px 2px;
    border-bottom: 1px solid var(--rule-soft);
}
.setting-row:last-child { border-bottom: 0; }
.setting-row > div { min-width: 0; }
.setting-row .k { font-weight: 500; }
.setting-row .v {
    font-size: .8rem;
    color: var(--text-dim);
    margin-top: 1px;
    font-family: var(--serif);
    font-style: italic;
}
.setting-row select, .setting-row input {
    flex: none;
    width: min(220px, 48%);
    min-width: 0;
    height: 38px;
    padding: 0 10px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    outline: none;
    transition: border-color .15s;
}
.setting-row select:focus, .setting-row input:focus { border-color: var(--accent); }
.setting-row select { text-overflow: ellipsis; }
/* A phone gives the control less than half the row: let a choice take what its words need. */
@media (max-width: 430px) { .setting-row select { width: auto; min-width: 48%; max-width: 62%; } }

.data-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; flex: none; }
#sync-box { margin-bottom: 12px; }
.sync-code {
    display: inline-block;
    margin-top: 6px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .86rem;
    letter-spacing: .04em;
    color: var(--text);
    user-select: all;
    word-break: break-all;
}
.sync-join { padding: 0 2px 14px; }
.sync-join label { display: block; font-size: .8rem; color: var(--text-dim); margin-bottom: 6px; }
.sync-join-row { display: flex; gap: 8px; }
.sync-join-row input {
    flex: 1;
    min-width: 0;
    height: 38px;
    padding: 0 10px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    text-transform: uppercase;
    outline: none;
}
.sync-join-row input:focus { border-color: var(--accent); }
@media (max-width: 520px) {
    .sync-row { flex-wrap: wrap; }
    .sync-row .data-actions { justify-content: flex-start; }
}

/* ---------- Plan the day, close the day (app.js) ---------- */

.board-bar { gap: 18px; }
.day-line { margin: 14px 0 0; font-family: var(--serif); font-size: 1rem; color: var(--text); display: flex; align-items: baseline; gap: 8px; }
.day-line.quiet { color: var(--text-dim); font-style: italic; }
.day-meter { margin-top: 12px; }
.day-meter-bar { position: relative; display: flex; height: 6px; border-radius: 3px; background: var(--surface-2); }
.day-meter-bar i { display: block; height: 100%; }
.day-meter-bar i.done { background: var(--fill, var(--accent)); border-radius: 3px 0 0 3px; }
.day-meter-bar i.open { background: color-mix(in srgb, var(--accent) 35%, transparent); }
.day-meter-bar i:last-of-type { border-radius: 0 3px 3px 0; }
.day-meter.over .day-meter-bar i.open { background: color-mix(in srgb, var(--warn) 55%, transparent); }
.day-meter-bar .holds { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--text); }
.day-meter-line {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 2px 12px;
    margin-top: 6px;
    font-size: .8rem;
    color: var(--text-dim);
}
.day-meter-line b { color: var(--text); font-weight: 600; }
.day-meter-line .warn { color: var(--warn); }
.day-meter-line .faint { color: var(--text-faint); }
.day-meter-line select {
    border: 0;
    border-bottom: 1px dashed var(--text-faint);
    background: none;
    color: var(--text);
    font: inherit;
    font-weight: 600;
    padding: 0 2px;
}

/* A length chip on today's list is a button: tap to step it on. */
button.chip.est { border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; }
button.chip.est.unset { color: var(--text-faint); font-style: italic; }

/* Could also fit: under today's list, folded after the morning. */
.fit { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--rule); }
.fit summary {
    cursor: pointer;
    list-style: none;
    padding: 6px 0;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.fit summary::-webkit-details-marker { display: none; }
.fit summary::before { content: '\25B8'; display: inline-block; margin-right: 6px; transition: transform .15s; }
.fit[open] summary::before { transform: rotate(90deg); }
.fit summary span { font-weight: 400; letter-spacing: 0; text-transform: none; font-size: .8rem; }
.fit-row, .closing-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--rule-soft);
}
.fit-row:last-of-type { border-bottom: 0; }
.fit-title { flex: 1; min-width: 0; color: var(--text-dim); }
.fit-why { display: block; font-size: .75rem; color: var(--text-faint); font-family: var(--serif); font-style: italic; }
.fit-add {
    flex: none;
    min-height: 32px;
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: var(--surface);
    color: var(--accent);
    font-size: .8rem;
    font-weight: 500;
}
.fit-add:hover { border-color: var(--accent); }
.fit-more { margin-top: 4px; font-size: .8rem; }

/* The evening card, at the top of Today. */
.closing {
    margin-top: 14px;
    padding: 14px 16px;
    border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--rule));
    border-radius: var(--radius);
    background: var(--surface);
}
.closing-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.closing-head b { font-family: var(--serif); font-size: 1.05rem; font-weight: 500; }
.closing-head span { flex: 1; font-size: .82rem; color: var(--text-dim); }
.closing-row { flex-wrap: wrap; }
.closing-row .fit-title { flex: 1 1 160px; color: var(--text); }
.closing-empty { margin: 4px 0; color: var(--text-dim); font-family: var(--serif); font-style: italic; }
.closing-form { display: flex; gap: 8px; margin-top: 12px; }
.closing-form input {
    flex: 1;
    min-width: 0;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--text);
    font-family: var(--serif);
    outline: none;
}
.closing-form input:focus { border-color: var(--accent); }
.seg { display: inline-flex; border: 1px solid var(--rule); border-radius: var(--radius-sm); overflow: hidden; flex: none; }
.seg button {
    min-height: 32px;
    padding: 0 10px;
    border: 0;
    border-left: 1px solid var(--rule);
    background: var(--surface);
    color: var(--text-dim);
    font-size: .8rem;
}
.seg button:first-child { border-left: 0; }
.seg button:hover { color: var(--accent); }

/* ---------- Phone navigation (app.js, wireBottomNav) ---------- */

.bottom-nav { display: none; }
@media (max-width: 760px) {
    :root { --nav-h: calc(58px + env(safe-area-inset-bottom, 0px)); }
    .tabs { display: none; }
    .bottom-nav {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 35;
        display: flex;
        height: var(--nav-h);
        padding-bottom: env(safe-area-inset-bottom, 0px);
        background: color-mix(in srgb, var(--bg) 96%, transparent);
        backdrop-filter: blur(12px);
        border-top: 1px solid var(--rule);
    }
    .bottom-nav > button {
        position: relative;
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        min-width: 0;
        border: 0;
        background: none;
        color: var(--text-faint);
        font-size: .68rem;
        font-weight: 500;
        letter-spacing: .01em;
        -webkit-tap-highlight-color: transparent;
    }
    .bottom-nav > button svg { width: 22px; height: 22px; }
    .bottom-nav > button[aria-current="page"], .bottom-nav > button.current { color: var(--accent); }
    .bottom-nav > button:active { opacity: .6; }
    .nav-pip {
        position: absolute;
        top: 5px;
        left: calc(50% + 6px);
        min-width: 17px;
        height: 17px;
        padding: 0 4px;
        border-radius: 9px;
        background: var(--fill, var(--accent));
        color: var(--on-fill, var(--surface));
        font-size: .64rem;
        font-weight: 600;
        line-height: 17px;
        text-align: center;
    }
    .nav-more {
        position: absolute;
        right: 8px;
        bottom: calc(100% + 8px);
        min-width: 170px;
        padding: 6px;
        border: 1px solid var(--rule);
        border-radius: var(--radius);
        background: var(--surface);
        box-shadow: 0 10px 30px rgb(0 0 0 / .16);
    }
    .nav-more button {
        display: flex;
        align-items: center;
        gap: 12px;
        width: 100%;
        min-height: 46px;
        padding: 0 12px;
        border: 0;
        border-radius: var(--radius-sm);
        background: none;
        color: var(--text);
        font-size: .95rem;
        text-align: left;
    }
    .nav-more button svg { width: 19px; height: 19px; color: var(--text-dim); }
    .nav-more button[aria-current="page"] { background: var(--surface-2); }

    /* Everything that sat on the bottom edge moves up above the bar. */
    .shell { padding-bottom: calc(104px + var(--nav-h)); }
    .capture { bottom: calc(var(--kb, 0px) + var(--nav-h)); padding-bottom: 11px; }
    .toast { bottom: calc(var(--nav-h) + 78px); }
    .edit-bar, .bulk-bar { bottom: calc(var(--nav-h) + 14px); }
    /* While typing, the keyboard needs the room: the bar steps aside. */
    body.keyboard-open .bottom-nav { display: none; }
    body.keyboard-open .capture { bottom: var(--kb, 0px); padding-bottom: calc(11px + env(safe-area-inset-bottom, 0px)); }
    body.keyboard-open .toast { bottom: calc(var(--kb, 0px) + 78px); }
}

/* ---------- Bigger targets for fingers ----------
 * The small round checks and icon buttons keep their look; on a touch
 * screen each gets an invisible 44px pad around it (Apple's minimum). */
@media (pointer: coarse) {
    .check, .habit-tick, .icon-btn, .nb-nav { position: relative; }
    .check::after, .habit-tick::after, .icon-btn::after, .nb-nav::after {
        content: '';
        position: absolute;
        left: 50%; top: 50%;
        width: 44px; height: 44px;
        translate: -50% -50%;
    }
    /* Not leftwards: the drag handle lives just left of the check. */
    .check::after { left: -3px; right: -12px; top: -12px; bottom: -12px; width: auto; height: auto; translate: none; }
    .icon-btn { padding: 8px; }
    .task-actions { gap: 4px; }
}

/* ---------- Filters ---------- */

.filter-row { display: flex; gap: 16px; margin-bottom: 8px; flex-wrap: wrap; align-items: center; }
.filter-row button {
    border: 0;
    border-bottom: 1px solid transparent;
    background: none;
    color: var(--text-faint);
    padding: 3px 0;
    border-radius: 0;
    font-size: .85rem;
    transition: color .15s, border-color .15s;
}
.filter-row button:hover { color: var(--text-dim); }
.filter-row button[aria-pressed="true"] {
    color: var(--text);
    border-bottom-color: var(--accent);
}

/* The day and weekday pickers keep a boxed look — they are controls, not prose. */
.sheet .filter-row button, #habit-days button, #rule-days button {
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 7px 11px;
    color: var(--text-dim);
}
.sheet .filter-row button[aria-pressed="true"],
#habit-days button[aria-pressed="true"],
#rule-days button[aria-pressed="true"] {
    background: var(--fill, var(--accent));
    border-color: var(--fill, var(--accent));
    color: var(--on-fill, var(--surface));
}
#habit-days, #rule-days { gap: 6px; }


/* ---------- Board ---------- */

.panel {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 12px 14px 14px;
    min-width: 0;
}
.panel.accent { border-color: color-mix(in srgb, var(--warn) 45%, var(--rule)); }

.panel-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding-bottom: 7px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--rule-soft);
}
.panel-title {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.02rem;
    font-weight: 500;
    flex: 1;
    min-width: 0;
}
.panel.accent .panel-title { color: var(--warn); }
.panel-note {
    font-size: .78rem;
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
    white-space: nowrap;
}

/* Inside a panel the rules are already provided by the panel border. */
.panel .section { margin-top: 0; }
.panel .task, .panel .habit, .panel .rule, .panel .shared-row { padding-left: 0; padding-right: 0; }
.panel .empty { padding: 12px 0; font-size: .86rem; }
.panel .momentum { padding-top: 10px; }
.panel .dayline { margin-top: 0; padding-top: 8px; border-top: 0; font-size: .95rem; }

/* Upcoming: tasks grouped under their day. */
.upcoming-day {
    font-family: var(--serif);
    font-style: italic;
    font-size: .8rem;
    color: var(--text-faint);
    margin: 10px 0 1px;
}
.upcoming-day:first-child { margin-top: 4px; }

/* The strip of modules you have put away. */
.panel-shelf {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-top: 26px;
    padding-top: 12px;
    border-top: 1px solid var(--rule-soft);
}
.panel-shelf .label {
    font-family: var(--serif);
    font-style: italic;
    font-size: .82rem;
    color: var(--text-faint);
}
.panel-shelf button {
    border: 1px solid var(--rule);
    background: var(--surface);
    color: var(--text-dim);
    border-radius: var(--radius);
    padding: 4px 10px;
    font-size: .82rem;
}
.panel-shelf button:hover { color: var(--text); border-color: var(--text-faint); }

/* ---------- Week view ---------- */

.week-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 18px;
}
.week-nav .range {
    font-family: var(--serif);
    font-size: 1.05rem;
    color: var(--text);
}

/* Seven days abreast once there is room for it; stacked when there is not. */
.week-grid { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr); }   /* never wider than the screen */
@media (min-width: 1000px) {
    /* Equal-height columns: a calendar reads as a grid, and a full-height
       column is a much easier drop target than one sized to its contents. */
    .week-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); align-items: stretch; }
    .week-grid .day {
        border: 1px solid var(--rule);
        border-radius: var(--radius);
        min-height: 200px;
        margin-bottom: 0;
        display: flex;
        flex-direction: column;
    }
    .week-grid .day-tasks { flex: 1; }
    /* Stack the day's name above its counts rather than running them together. */
    .week-grid .day-name, .week-grid .day-count { display: block; }
    .week-grid .day.today { border-color: color-mix(in srgb, var(--accent) 50%, var(--rule)); }
    .week-grid .day-head { display: block; padding: 8px 9px 5px; }
    .week-grid .day-count { text-align: left; margin-top: 1px; }
    .week-grid .wtitle { white-space: normal; overflow: visible; line-height: 1.35; }
    .week-grid .wtask { align-items: flex-start; font-size: .85rem; }
    .week-grid .wtask .bar { min-height: 1.1em; }
}

/* The backlog is a strip you pull from, so it flows rather than stacking. */
@media (min-width: 1000px) {
    .backlog-head .day-tasks { display: flex; flex-wrap: wrap; gap: 4px; }
    .backlog-head .wtask { flex: 0 1 auto; max-width: 320px; border: 1px solid var(--rule); }
}

.day {
    margin-bottom: 2px;
    border-radius: var(--radius);
    transition: background .15s;
}
.day.today { background: color-mix(in srgb, var(--accent) 7%, var(--bg)); }
.day.past .day-name { color: var(--text-dim); }
.day.drop-target { background: var(--surface-2); outline: 1px dashed var(--accent); }

.day-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 9px 10px 5px;
    border-bottom: 1px solid var(--rule-soft);
}
.day-name { font-family: var(--serif); font-size: .98rem; font-weight: 500; }
/* Today's name in the text colour, marked by an accent underline, so it reads on its tint. */
.day.today .day-name { color: var(--text); text-decoration: underline 2px var(--accent); text-underline-offset: 4px; }
.day-count {
    font-size: .76rem;
    color: var(--text-dim);
    font-family: var(--serif);
    font-style: italic;
    text-align: right;
}

.day-tasks { padding: 4px 4px 8px; min-height: 6px; }
.day-empty {
    padding: 7px 6px;
    color: var(--text-faint);
    font-size: .82rem;
    font-family: var(--serif);
    font-style: italic;
}

.wtask {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px;
    border-radius: var(--radius-sm);
    font-size: .89rem;
    cursor: grab;
    transition: background .12s;
}
.wtask:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
.wtask.dragging { opacity: .35; }
.wtask.done .wtitle { color: var(--text-dim); text-decoration: line-through; }
.wtask .bar { width: 2px; align-self: stretch; border-radius: 1px; background: var(--rule); flex: 0 0 auto; }
.wtitle { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtask .repeat { color: var(--text-faint); flex: 0 0 auto; line-height: 0; }
.wtask .repeat svg { width: 12px; height: 12px; }

.backlog-head { margin-top: 26px; }

/* ---------- Repeating rules ---------- */

.rule {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 2px;
    border-bottom: 1px solid var(--rule-soft);
}
.rule:last-child { border-bottom: 0; }
.rule-body { flex: 1; min-width: 0; }
.rule-name { font-weight: 500; }
.rule-sub {
    font-size: .8rem;
    color: var(--text-dim);
    margin-top: 1px;
    font-family: var(--serif);
    font-style: italic;
}

.inline-fields { display: flex; gap: 10px; flex-wrap: wrap; }
.inline-fields .field { flex: 1; min-width: 118px; margin-bottom: 0; }

/* ---------- Day picker sheet ---------- */

.sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: 70;
    background: color-mix(in srgb, var(--text) 40%, transparent);
    display: grid;
    place-items: end center;
    padding: 16px;
}
.sheet {
    width: 100%;
    max-width: 400px;
    max-height: calc(100dvh - 32px - 78px - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 18px;
    margin-bottom: calc(78px + env(safe-area-inset-bottom, 0px));
}
.sheet h3 { margin: 0 0 2px; font-family: var(--serif); font-size: 1.1rem; font-weight: 500; }
.sheet p.sub {
    margin: 0 0 14px;
    font-size: .85rem;
    color: var(--text-dim);
    font-family: var(--serif);
    font-style: italic;
}

@media (max-width: 430px) {
    /* Room at the end for the capture bar and the bottom navigation both. */
    .shell { padding: 0 16px calc(104px + var(--nav-h, 0px)); }
    .panel { padding: 11px 12px 12px; }
    .capture { padding-left: 16px; padding-right: 16px; }
    .greeting { font-size: 1.45rem; }
    .tabs { gap: 14px; }
    .tabs button { font-size: .85rem; }
}

/* ---------- Widget personalisation ---------- */

/* A widget's accent tints its rule and title only — never its whole body.
   A board of six coloured blocks is harder to read, not more personal. */
.panel[data-accent="ochre"]   { --w: var(--warn); }
.panel[data-accent="pine"]    { --w: var(--w-pine, #3d6353); }
.panel[data-accent="oxblood"] { --w: var(--danger); }
.panel[data-accent="slate"]   { --w: var(--w-slate, #41627a); }
.panel[data-accent="plum"]    { --w: var(--w-plum, #6b4a63); }
.panel[data-accent="moss"]    { --w: var(--w-moss, #5a6b33); }
/* (A theme sets --w-* made readable on its own page: paintFor in app.js.) */
.panel[data-accent] { border-color: color-mix(in srgb, var(--w) 45%, var(--rule)); }
.panel[data-accent] .panel-title { color: var(--w); }
.panel[data-accent] .panel-head { border-bottom-color: color-mix(in srgb, var(--w) 25%, var(--rule-soft)); }

/* A note widget is the one place free text lives on the board. */
.note-body {
    width: 100%;
    min-height: 90px;
    border: 0;
    background: none;
    outline: none;
    resize: vertical;
    padding: 8px 0 0;
    line-height: 1.6;
    font-family: var(--serif);
    color: var(--text);
}
.note-body::placeholder { color: var(--text-faint); font-style: italic; }

/* ---------- Sheets used for widget settings and the widget picker ---------- */

.sheet.wide { max-width: 520px; }
.sheet-scroll { max-height: min(70vh, 560px); overflow-y: auto; }
.sheet-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--rule-soft);
}
.sheet-actions .spacer { flex: 1; }

/* ---------- Widget picker ---------- */
/* A picture of each widget, drawn with the theme cards' parts (tp-*) in the
   current theme, with its name beneath. What it does slides over the
   picture on hover or keyboard focus; without hover it sits under the name. */
.sheet.picker { max-width: 820px; }   /* ten widgets: two rows of five */
.type-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 10px;
}
.type-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 6px 6px 8px;
    text-align: left;
    border: 1px solid var(--rule);
    background: var(--surface);
    border-radius: calc(var(--radius) + 2px);
    color: var(--text);
    transition: border-color .15s, box-shadow .15s;
}
.type-card:hover { border-color: var(--accent); }
.type-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.type-name { padding: 0 3px; font-size: .84rem; font-weight: 500; line-height: 1.2; }
.type-desc {
    font-size: .76rem;
    color: var(--text-dim);
    font-family: var(--serif);
    font-style: italic;
    line-height: 1.35;
}

.type-preview {
    display: flex;
    height: 84px;
    padding: 7px;
    border-radius: var(--radius);
    background: var(--bg);
    border: 1px solid var(--rule-soft);
    overflow: hidden;
    pointer-events: none;
}
.type-preview .tp-panel { gap: 6px; }
.type-preview .tp-head { flex: none; width: 38%; height: 4px; background: var(--text-dim); }

@media (hover: hover) {
    .type-desc {
        position: absolute;
        inset: 6px 6px auto;
        height: 84px;
        display: flex;
        align-items: center;
        padding: 8px 10px;
        border-radius: var(--radius);
        background: var(--surface);
        border: 1px solid var(--accent);
        color: var(--text);
        opacity: 0;
        transform: translateY(3px);
        transition: opacity .15s, transform .15s;
        pointer-events: none;
    }
    .type-card:hover .type-desc, .type-card:focus-visible .type-desc {
        opacity: 1;
        transform: none;
    }
}
@media (hover: none) {
    .type-desc { padding: 0 3px; }
}

/* The miniatures' own parts. */
.wp-box { flex: none; width: 8px; height: 8px; border-radius: 2px; border: 1px solid var(--rule); background: var(--surface); }
.wp-box.on { background: var(--good); border-color: var(--good); }
.wp-streak { height: 3px; width: 14%; border-radius: 2px; background: var(--warn); margin-left: auto; }
.wp-sentence { gap: 4px; }
.wp-strong { flex: none; width: 7px; height: 5px; border-radius: 1px; background: var(--text); }
.wp-bars { flex: 1; display: flex; align-items: flex-end; gap: 3px; padding-top: 4px; }
.wp-bars span { flex: 1; background: var(--fill, var(--accent)); border-radius: 1px 1px 0 0; opacity: .85; }
.wp-bars span.none { background: var(--surface-2); opacity: 1; }
.wp-bars span.today { background: var(--warn); }
.wp-center { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; }
.wp-ring { width: 38px; height: 38px; }
.wp-rings .wp-ring { width: 22px; height: 22px; }
.wp-count { flex-direction: column; gap: 3px; }
.wp-count b { font-family: var(--serif); font-weight: 500; font-size: 1.35rem; line-height: 1; color: var(--text); }
.wp-count .tp-line.faint { flex: 0 0 3px; width: 34px; }
.wp-heat { flex: 1; display: grid; grid-template-columns: repeat(12, 1fr); gap: 2px; align-content: center; }
.wp-heat span { aspect-ratio: 1; border-radius: 1px; background: var(--fill, var(--accent)); }
.wp-heat .l0 { background: var(--surface-2); }
.wp-heat .l1 { opacity: .3; }
.wp-heat .l2 { opacity: .5; }
.wp-heat .l3 { opacity: .75; }
.wp-repeat { flex: none; display: flex; color: var(--text-faint); }
.wp-repeat svg { width: 8px; height: 8px; }
.wp-note { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 7px; }
.wp-note span { display: block; height: 2px; width: 88%; border-radius: 2px; background: var(--text-faint); opacity: .7; }

@media (max-width: 480px) {
    .type-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .type-preview { height: 70px; }
    .wp-ring { width: 30px; height: 30px; }
}

/* Colour swatches, used for widget accents and the app accent. */
.swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.swatch {
    width: 30px; height: 30px;
    border-radius: 50%;
    border: 1px solid var(--rule);
    padding: 0;
    position: relative;
}
.swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--text-dim); }
.swatch.none {
    background: var(--surface);
    color: var(--text-faint);
    font-size: .95rem;
    line-height: 28px;
}

.choice-row { display: flex; flex-wrap: wrap; gap: 6px; }
.choice-row button {
    border: 1px solid var(--rule);
    background: var(--surface);
    color: var(--text-dim);
    border-radius: var(--radius);
    padding: 7px 12px;
    font-size: .85rem;
}
.choice-row button[aria-pressed="true"] {
    background: var(--fill, var(--accent));
    border-color: var(--fill, var(--accent));
    color: var(--on-fill, var(--bg));
}

/* ---------- Theme picker ---------- */
/* Each card is a miniature of the app drawn in that theme's own variables
   (set inline by themeMini() in app.js): paper, a panel, a heading, a done and an open
   task, a late note and the accent's button. Clicking one applies it. */
.theme-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 10px;
}
.theme-card {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 6px 6px 8px;
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 2px);
    background: var(--surface);
    color: var(--text-dim);
    text-align: left;
    transition: border-color .15s, box-shadow .15s;
}
.theme-card:hover { border-color: var(--text-faint); }
.theme-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-card[aria-pressed="true"] {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
    color: var(--text);
}
.theme-name {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 0 3px;
    font-size: .82rem;
    line-height: 1.2;
}
.theme-name svg { width: 14px; height: 14px; color: var(--accent); flex: none; opacity: 0; }
.theme-card[aria-pressed="true"] .theme-name svg { opacity: 1; }

.theme-preview {
    display: flex;
    height: 78px;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
    pointer-events: none;
}
.tp {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 8px;
    background: var(--bg);
}
.tp-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 6px 7px;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 3px;
}
.tp-head { height: 5px; width: 46%; border-radius: 2px; background: var(--text); }
.tp-row { display: flex; align-items: center; gap: 5px; }
.tp-check {
    flex: none;
    width: 7px; height: 7px;
    border-radius: 50%;
    border: 1px solid var(--text-faint);
}
.tp-check.done { background: var(--fill, var(--accent)); border-color: var(--fill, var(--accent)); }
.tp-line { height: 3px; flex: 0 1 70%; border-radius: 2px; background: var(--text-dim); }
.tp-line.faint { background: var(--text-faint); flex-basis: 45%; }
.tp-late { height: 3px; width: 16%; border-radius: 2px; background: var(--warn); margin-left: auto; }
.tp-foot { display: flex; gap: 4px; }
.tp-input { flex: 1; height: 9px; border-radius: 2px; background: var(--surface); border: 1px solid var(--rule); }
.tp-btn { width: 20px; height: 9px; border-radius: 2px; background: var(--fill, var(--accent)); }
/* "Match my system" is drawn as both halves, day and night. */
.theme-preview.split .tp { padding: 8px 5px; }
.theme-preview.split .tp + .tp { border-left: 1px solid color-mix(in srgb, var(--text) 12%, transparent); }
@media (max-width: 480px) {
    /* Three to a row keeps nine themes to a glance instead of a long scroll. */
    .theme-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
    .theme-card { padding: 4px 4px 6px; gap: 5px; }
    .theme-preview { height: 60px; }
    .tp { padding: 6px; gap: 4px; }
    .tp-panel { padding: 5px; gap: 4px; }
    .theme-name { font-size: .76rem; }
}

/* ---------- Morning check-in ---------- */

.sheet.checkin { max-width: 520px; }
.checkin-sheet h3 { margin-bottom: 4px; }
.checkin-progress {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    font-size: .8rem;
    color: var(--text-faint);
}
.checkin-dots { display: flex; gap: 5px; }
.checkin-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--rule); }
.checkin-dots span.past { background: var(--text-faint); }
.checkin-dots span.now { background: var(--warn); }
.checkin-task { font-size: 1.3rem !important; line-height: 1.3; }
.checkin-choices { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 10px; }
.checkin-choices .btn { flex: 1 1 auto; }
.checkin-choices .letgo { color: var(--text-dim); border-style: dashed; }
.checkin-note { margin: 0 0 4px; font-size: .8rem; color: var(--text-faint); font-family: var(--serif); font-style: italic; }
.checkin-tally { margin: 12px 0; padding: 0; list-style: none; }
.checkin-tally li { padding: 4px 0; border-bottom: 1px solid var(--rule-soft); }
.checkin-tally b { display: inline-block; min-width: 26px; font-family: var(--serif); font-size: 1.1rem; }

.widget-foot { display: flex; gap: 16px; padding-top: 10px; border-top: 1px solid var(--rule-soft); }
.link-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-dim);
    font-size: .82rem;
    text-decoration: underline;
    text-decoration-color: var(--rule);
    text-underline-offset: 3px;
}
.link-btn:hover { color: var(--text); text-decoration-color: currentColor; }
a.btn { text-decoration: none; }
.letgo-row { align-items: center; }
.letgo-row .task-title { color: var(--text-dim); }

/* ---------- Daily rhythm ---------- */

/* ---- Nudges ----
   One line above the board in the voice of a margin note: a dot for what
   kind of thing it is (ochre: carried over; accent: an invitation), a serif
   sentence, the actions as links, and a × that folds it away. No box, so it
   never competes with the panels or with the demo notice. */
.nudge {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 16px;
    padding: 2px 0;
    overflow: hidden;
    animation: nudge-in .28s ease both;
    transition: height .22s ease, opacity .18s ease, margin .22s ease, padding .22s ease;
}
.nudge.folding, .welcome.folding { height: 0 !important; opacity: 0; margin-top: 0; padding: 0; }

/* A new planner's welcome: a card of three first steps that tick themselves off. */
.welcome {
    margin-top: 16px;
    padding: 14px 16px 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
    animation: nudge-in .28s ease both;
    transition: height .22s ease, opacity .18s ease, margin .22s ease, padding .22s ease;
}
.welcome-head { display: flex; align-items: flex-start; gap: 10px; }
.welcome-head p { flex: 1; margin: 0; font-family: var(--serif); font-size: 1.05rem; line-height: 1.5; color: var(--text-dim); }
.welcome-head b { font-weight: 500; color: var(--text); }
.welcome-steps { list-style: none; margin: 8px 0 0; padding: 0; }
.welcome-steps li { display: flex; gap: 12px; align-items: flex-start; padding: 9px 0; border-top: 1px solid var(--rule); }
.welcome-steps li:first-child { border-top: 0; }
.welcome-tick {
    flex: none; width: 22px; height: 22px; margin-top: 1px; border-radius: 50%;
    border: 1.5px solid var(--text-faint); display: grid; place-items: center; color: transparent;
    transition: background .2s, border-color .2s, color .2s;
}
.welcome-tick svg { width: 12px; height: 12px; }
.welcome-steps li.done .welcome-tick { background: var(--good); border-color: var(--good); color: var(--bg); }
.welcome-go { flex: 1; min-width: 0; padding: 0; border: 0; background: none; text-align: left; color: var(--text); cursor: pointer; }
.welcome-go > span { display: block; font-weight: 500; }
.welcome-go small { display: block; margin-top: 2px; font-size: .84rem; color: var(--text-faint); }
.welcome-steps li:not(.done) .welcome-go > span { color: var(--accent); }
.welcome-steps li.done .welcome-go { cursor: default; }
.welcome-steps li.done .welcome-go > span { color: var(--text-faint); text-decoration: line-through; text-decoration-color: var(--rule); }
.welcome-end { margin: 8px 0 0; font-family: var(--serif); font-size: .98rem; line-height: 1.5; color: var(--text-dim); }
@media (prefers-reduced-motion: reduce) { .welcome { animation: none; transition: none; } }

/* ---------- The tour ----------
   The page itself, dimmed as behind a sheet, with one place lit. The card
   holds still: one place (just under the header, where the eye rests, set
   from app.js as --tour-top) and one size the whole way, so only the light
   and the page behind it move, in the space below the card. The whole layer
   takes the taps, so nothing underneath changes. */
.tour {
    position: fixed; inset: 0; z-index: 75;
    --tour-dim: color-mix(in srgb, var(--text) 40%, transparent);
    background: transparent;
    transition: background-color .18s ease;
    animation: tour-in .2s ease both;
}
/* Nothing lit (the first and last steps), or between two tabs: all of it dimmed. */
.tour.no-spot, .tour.between { background: var(--tour-dim); }
.tour-spot {
    position: fixed;
    border-radius: var(--radius);
    box-shadow: 0 0 0 200vmax var(--tour-dim);
    outline: 2px solid var(--accent);
    pointer-events: none;
    transition: left .3s ease, top .3s ease, width .3s ease, height .3s ease, opacity .18s ease;
}
.tour.tracking .tour-spot { transition: opacity .18s ease; }
.tour.no-spot .tour-spot, .tour.between .tour-spot { opacity: 0; }
.tour-card {
    position: fixed;
    left: 50%;
    top: var(--tour-top, 16px);
    transform: translateX(-50%);
    width: min(480px, calc(100vw - 32px));
    max-height: calc(100dvh - var(--tour-top, 16px) - 16px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    padding: 18px 18px 12px;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    outline: none;
}
.tour-progress { position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--rule-soft); }
.tour-progress i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .3s ease; }
/* Spread across the card like a line to walk along; one line even on a small phone. */
.tour-chapters {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 8px;
    margin: 0 0 12px; padding: 0; list-style: none;
    font-size: .76rem; color: var(--text-faint);
}
.tour-chapters li.past { color: var(--text-dim); }
.tour-chapters li.on {
    color: var(--text);
    text-decoration: underline 2px var(--accent);
    text-underline-offset: 4px;
}
.tour-body { transition: opacity .14s ease; }
.tour-body.fading { opacity: 0; }
.tour-card h3 { margin: 0 0 6px; font-family: var(--serif); font-size: 1.15rem; font-weight: 500; }
.tour-text { margin: 0; font-family: var(--serif); font-size: 1rem; line-height: 1.5; color: var(--text-dim); }
.tour-text b { font-family: var(--sans); font-size: .9em; font-weight: 600; color: var(--text); }
.tour-where, .tour-demo { margin: 8px 0 0; font-size: .84rem; color: var(--text-faint); }
.tour-body { margin-bottom: 14px; }
/* Pinned to the bottom of the card, so the buttons stay put whatever the step says. */
.tour-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-top: auto; padding-top: 12px; border-top: 1px solid var(--rule-soft);
}
.tour-actions .spacer { flex: 1; }
/* Room to scroll the last places of a page up into view above the card. */
.tour-room { height: 70vh; }
@keyframes tour-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .tour, .tour-spot, .tour-body, .tour-progress i { transition: none; animation: none; }
}
@keyframes nudge-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
    .nudge { animation: none; transition: none; }
}
.nudge-dot {
    flex: none;
    width: 7px;
    height: 7px;
    margin-top: .62em;
    border-radius: 50%;
    background: var(--fill, var(--accent));
}
.nudge-warn .nudge-dot { background: var(--warn); }
.nudge-text {
    flex: 1;
    min-width: 0;
    font-family: var(--serif);
    font-size: 1rem;
    line-height: 1.55;
    color: var(--text-dim);
}
.nudge-text b { font-weight: 500; color: var(--text); }
.nudge-warn .nudge-text b { color: var(--warn); }
.nudge-act {
    margin-left: 4px;
    padding: 0;
    border: 0;
    background: none;
    font-family: var(--sans);
    font-size: .86rem;
    font-weight: 500;
    color: var(--accent);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
    text-underline-offset: 3px;
}
.nudge-act:hover { text-decoration-color: currentColor; }
.nudge-sep { margin: 0 2px 0 6px; color: var(--text-faint); }
.nudge-x {
    flex: none;
    width: 26px;
    height: 26px;
    margin-top: 1px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--text-faint);
    font-size: 1.15rem;
    line-height: 1;
}
.nudge-x:hover, .nudge-x:focus-visible { opacity: 1; background: var(--surface-2); color: var(--text); }
.nudge-form { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.nudge-form input {
    flex: 1 1 220px;
    min-width: 0;
    height: 32px;
    padding: 0 10px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    font-family: var(--sans);
    font-size: .92rem;
    color: var(--text);
    outline: none;
}
.nudge-form input:focus { border-color: var(--accent); }
.nudge-form .nudge-act { margin-left: 0; }

/* "What next?" sits in the header beside the date, on Today only. */

.focus-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 14px; }
.focus-label {
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.focus-item {
    padding: 4px 10px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    font-size: .86rem;
}
.focus-item:hover { border-color: var(--accent); }
.focus-item.done { color: var(--text-faint); text-decoration: line-through; background: none; }
.lighten-list { margin: 8px 0 4px; }
.lighten-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 2px;
    border-bottom: 1px solid var(--rule-soft);
    cursor: pointer;
}
.lighten-row input { width: 17px; height: 17px; accent-color: var(--accent); flex: none; }
.lighten-row.locked { cursor: default; color: var(--text-dim); }
.lighten-title { flex: 1; min-width: 0; }
.lighten-meta { font-size: .78rem; color: var(--text-faint); font-family: var(--serif); font-style: italic; }

.sheet.review-sheet { max-width: 560px; }
.review h3 { margin-bottom: 2px; }
.review-block { padding: 14px 0; border-top: 1px solid var(--rule-soft); }
.review-block:first-of-type { margin-top: 10px; }
.review-block h4 {
    margin: 0 0 8px;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.review-block p { margin: 0; }
.review-big b { font-family: var(--serif); font-size: 1.8rem; font-weight: 500; margin-right: 4px; }
.review-block .review-trend { margin-top: 2px; font-size: .82rem; color: var(--text-faint); }
.review-list, .review-notes, .review-habits { margin: 8px 0 0; padding: 0; list-style: none; }
.review-list li { padding: 3px 0; font-size: .9rem; color: var(--text-dim); }
.review-list li::before { content: "\2713"; color: var(--good); margin-right: 8px; }
.review-list li.more::before { content: ""; margin: 0; }
.review-notes li { padding: 4px 0; font-family: var(--serif); font-style: italic; }
.review-notes li span { font-style: normal; font-family: var(--sans); font-size: .76rem; color: var(--text-faint); margin-right: 6px; }
.review-habits li { display: grid; grid-template-columns: minmax(0, 1fr) 90px auto; align-items: center; gap: 10px; padding: 4px 0; font-size: .9rem; }
.review-bar { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.review-bar span { display: block; height: 100%; background: var(--good); }
.review-count { font-size: .78rem; color: var(--text-faint); min-width: 44px; text-align: right; }
.review-input {
    display: block;
    width: 100%;
    height: 38px;
    margin-top: 8px;
    padding: 0 10px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    outline: none;
}
.review-input:focus { border-color: var(--accent); }


/* ---------- Notebook ---------- */

/* Pages down the side, the open page as a sheet of paper. On a phone, one
   at a time: the page, with "All notes" to get back to the list. */
.nb {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 32px;
    max-width: 1060px;
    margin: 22px auto 0;
    align-items: start;
}
.nb-side { position: sticky; top: 140px; display: flex; flex-direction: column; gap: 14px; }
.nb-search {
    height: 36px;
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: var(--surface);
    outline: none;
}
.nb-search:focus { border-color: var(--accent); }
.nb-group { display: flex; flex-direction: column; gap: 2px; }
.nb-group-title {
    margin: 0 0 4px 10px;
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.nb-item {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 7px 10px;
    border: 0;
    border-radius: var(--radius);
    background: none;
    text-align: left;
}
.nb-item:hover { background: var(--surface-2); }
.nb-item.open { background: var(--surface); box-shadow: inset 2px 0 0 var(--accent); }
.nb-item-title { font-size: .9rem; font-weight: 500; color: var(--text); }
.nb-item-sub {
    font-size: .78rem;
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nb-item-sub mark { background: var(--warn-soft); color: var(--text); font-style: normal; border-radius: 2px; }
.nb-new {
    margin-top: 4px;
    padding: 6px 10px;
    border: 1px dashed var(--rule);
    border-radius: var(--radius);
    background: none;
    color: var(--text-dim);
    font-size: .84rem;
    text-align: left;
}
.nb-new:hover { color: var(--text); border-color: var(--text-faint); }
.nb-empty { margin: 2px 10px; font-size: .8rem; color: var(--text-faint); font-family: var(--serif); font-style: italic; }

.nb-page {
    min-height: 60vh;
    padding: 22px 28px 26px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
}
.nb-head { display: flex; align-items: center; gap: 8px; }
.nb-title {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-family: var(--serif);
    font-size: 1.55rem;
    font-weight: 400;
    line-height: 1.2;
}
.nb-title-input { padding: 0; border: 0; background: none; color: var(--text); outline: none; }
.nb-nav {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--text-faint);
    flex: none;
}
.nb-nav:hover { background: var(--surface-2); color: var(--text); }
.nb-nav svg { width: 16px; height: 16px; }
.nb-nav.flip svg { transform: scaleX(-1); }
.nb-status {
    /* A fixed width, so "Saving…" and "Saved" never push the title about. */
    flex: none;
    width: 4.6rem;
    font-size: .74rem;
    color: var(--text-faint);
    text-align: right;
    white-space: nowrap;
}
.nb-delete { flex: none; }
.nb-back { display: none; }

.nb-well {
    display: flex;
    flex-wrap: wrap;            /* on a phone the line goes under its label, so it is not cut short */
    align-items: baseline;
    gap: 4px 10px;
    margin: 10px 0 4px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--rule-soft);
}
.nb-well span { flex: none; font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); }
.nb-well input {
    flex: 1 1 220px;
    min-width: 0;
    padding: 2px 0;
    border: 0;
    border-bottom: 1px dashed transparent;
    background: none;
    font-family: var(--serif);
    font-style: italic;
    font-size: 1rem;
    color: var(--text);
    outline: none;
}
.nb-well input:focus { border-bottom-color: var(--rule); }

/* The writing: a sheet of paper that grows with the entry. Serif, generous
   line height, no box inside the box. */
.nb-writing {
    display: block;
    width: 100%;
    min-height: 280px;
    margin: 14px 0 6px;
    padding: 0;
    border: 0;
    background: none;
    resize: none;
    overflow: hidden;
    outline: none;
    font-family: var(--serif);
    font-size: 1.12rem;
    line-height: 1.75;
    color: var(--text);
}
.nb-writing::placeholder { color: var(--text-faint); font-style: italic; }
.nb-selection { margin: 0 0 8px; }
.nb-selection .nudge-act { margin: 0; }
.nb-selection span { font-style: italic; }
.nb-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 16px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--rule-soft);
}
.nb-page .nb-well { margin: 8px 0 0; padding: 12px 0 0; border-top: 1px solid var(--rule-soft); border-bottom: 0; }

/* Plans from an entry: a checklist to approve, each with where it came from. */
.plan-task { background: var(--accent-soft); color: var(--accent); }
.plan-habit { background: color-mix(in srgb, var(--good) 16%, var(--bg)); color: var(--good); }
.plan-focus { background: var(--warn-soft); color: var(--warn); }

.nb-hint { margin: 0; flex: 1 1 240px; font-size: .78rem; color: var(--text-faint); font-family: var(--serif); font-style: italic; }
.nb-hint b { font-family: var(--sans); font-style: normal; font-weight: 600; color: var(--text-dim); }

@media (max-width: 760px) {
    .nb { grid-template-columns: minmax(0, 1fr); gap: 16px; margin-top: 16px; }
    .nb-side { position: static; }
    .nb-view-page .nb-side { display: none; }
    .nb-view-list .nb-page { display: none; }
    .nb-back {
        display: inline-block;
        margin: -6px 0 10px -2px;
        padding: 2px 0;
        border: 0;
        background: none;
        color: var(--text-dim);
        font-size: .85rem;
    }
    .nb-page { padding: 16px 16px 20px; min-height: 70vh; }
    .nb-title { font-size: 1.3rem; }
}

/* ---------- More widgets ---------- */


/* An "add" line inside a widget: quiet until used. */
.widget-add { margin-top: 6px; }
.widget-add input {
    width: 100%;
    height: 34px;
    padding: 0 2px;
    border: 0;
    border-bottom: 1px dashed var(--rule);
    background: none;
    color: var(--text);
    outline: none;
}
.widget-add input::placeholder { color: var(--text-faint); font-family: var(--serif); font-style: italic; }
.widget-add input:focus { border-bottom-color: var(--accent); border-bottom-style: solid; }

/* Today by the hour */
.agenda { padding-top: 4px; }
.ag-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: start; }
.ag-time { padding-top: 13px; font-size: .8rem; font-weight: 500; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.ag-row.past .ag-time { color: var(--text-faint); }
.ag-task .task { border-bottom: 1px solid var(--rule-soft); }
.ag-now { position: relative; height: 0; margin: 2px 0; border-top: 2px solid var(--accent); }
.ag-now span {
    position: absolute; left: 0; top: -10px; padding: 0 6px 0 0;
    background: var(--under, var(--bg)); color: var(--accent);
    font-size: .68rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
}
.ag-any { margin: 14px 0 0; font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); }

/* Up next */
.next { padding: 8px 0 4px; }
.next-when { font-size: .78rem; font-weight: 600; letter-spacing: .03em; color: var(--accent); }
.next-title { margin: 4px 0 6px; font-family: var(--serif); font-size: 1.35rem; line-height: 1.25; }
.next-actions { display: flex; gap: 8px; margin-top: 12px; }

/* Deadlines */
.dl { display: flex; align-items: flex-start; gap: 10px; }
.dl .task { flex: 1; min-width: 0; }
.dl-badge {
    flex: none; min-width: 64px; margin-top: 11px; padding: 2px 6px; border-radius: 999px;
    text-align: center; font-size: .72rem; font-weight: 600;
    background: var(--surface-2); color: var(--text-dim);
}
.dl-badge.soon { background: var(--warn-soft); color: var(--warn); }
.dl-badge.now { background: color-mix(in srgb, var(--danger) 14%, var(--bg)); color: var(--danger); }

/* Month */
.mo-head { display: flex; align-items: center; justify-content: space-between; margin: 2px 0 8px; font-family: var(--serif); }
.mo-nav { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-faint); }
.mo-nav:hover { background: var(--surface-2); color: var(--text); }
.mo-nav svg { width: 15px; height: 15px; }
.mo-nav.flip svg { transform: scaleX(-1); }
.mo-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mo-wd { text-align: center; font-size: .66rem; font-weight: 600; color: var(--text-faint); padding-bottom: 2px; }
.mo-day {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 4px 0 3px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text);
}
.mo-day b { font-size: .8rem; font-weight: 500; }
.mo-day:hover { background: var(--surface-2); }
.mo-day.past b { color: var(--text-faint); }
.mo-day.today { background: var(--fill, var(--accent)); }
.mo-day.today b { color: var(--bg); font-weight: 600; }
.mo-dots { display: flex; gap: 2px; height: 4px; }
.mo-dots em { width: 4px; height: 4px; border-radius: 50%; background: var(--fill, var(--accent)); }
.mo-dots em.due { background: var(--danger); }
.mo-day.today .mo-dots em { background: var(--bg); }

/* This week's three */
.three { display: flex; flex-direction: column; gap: 6px; padding: 6px 0 2px; }
.three-item { display: flex; align-items: center; gap: 10px; padding: 6px 2px; border: 0; background: none; text-align: left; font-size: .98rem; color: var(--text); }
.three-box {
    display: grid; place-items: center; flex: none; width: 24px; height: 24px; border-radius: 50%;
    border: 1.5px solid var(--rule); font-size: .76rem; font-weight: 600; color: var(--text-dim);
}
.three-box svg { width: 12px; height: 12px; stroke: var(--bg); }
.three-item.done .three-box { background: var(--good); border-color: var(--good); }
.three-item.done > span:last-child { color: var(--text-faint); text-decoration: line-through; }
.three-set { display: flex; flex-direction: column; gap: 6px; }
.three-set input { height: 34px; padding: 0 10px; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface); outline: none; }
.three-set input:focus { border-color: var(--accent); }
.three-set .btn { align-self: flex-start; margin-top: 4px; }
.three-edit { align-self: flex-start; margin-top: 2px; font-size: .85rem; }

/* Checklist */
.cl-item { display: flex; align-items: center; gap: 6px; border-bottom: 1px solid var(--rule-soft); }
.cl-item label { flex: 1; display: flex; align-items: center; gap: 10px; min-width: 0; padding: 8px 0; cursor: pointer; }
.cl-item input { width: 17px; height: 17px; flex: none; accent-color: var(--good); }
.cl-item.done label span { color: var(--text-faint); text-decoration: line-through; }
.cl-remove {
    flex: none; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%;
    background: none; color: var(--text-faint); font-size: 1.1rem; opacity: 0; transition: opacity .12s;
}
.cl-item:hover .cl-remove, .link-row:hover .cl-remove, .cl-remove:focus-visible { opacity: 1; }
@media (hover: none) { .cl-remove { opacity: .6; } }
.cl-remove:hover { background: var(--surface-2); color: var(--text); }

/* Counter */
.counter { padding: 6px 0 2px; }
.counter-main { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.counter-btn {
    width: 44px; height: 44px; padding: 0; border: 1px solid var(--rule); border-radius: 50%;
    background: var(--surface); color: var(--text); font-size: 1.4rem; line-height: 1;
}
.counter-btn.plus { background: var(--fill, var(--accent)); border-color: var(--fill, var(--accent)); color: var(--on-fill, var(--bg)); }
.counter-btn:disabled { opacity: .35; }
.counter-num { text-align: center; }
.counter-num b { display: block; font-family: var(--serif); font-size: 2.4rem; font-weight: 400; line-height: 1; }
.counter-num span { font-size: .8rem; color: var(--text-dim); }
.counter-bar { height: 6px; margin: 12px 0 10px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.counter-bar span { display: block; height: 100%; background: var(--good); }
.counter-week { display: flex; align-items: flex-end; gap: 4px; height: 30px; }
.counter-week i { flex: 1; border-radius: 2px 2px 0 0; background: var(--surface-2); }
.counter-week i.met { background: var(--good); }
.counter-week i:last-child { outline: 1px solid var(--accent); outline-offset: 1px; }

/* Focus timer */
.timer { text-align: center; padding: 8px 0 4px; }
.timer-phase { font-size: .74rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.timer-clock { margin: 4px 0 10px; font-family: var(--serif); font-size: 3rem; line-height: 1; font-variant-numeric: tabular-nums; }
.timer-actions { display: flex; justify-content: center; gap: 8px; }
.timer-sub { margin-top: 10px; font-size: .76rem; color: var(--text-faint); }

/* Journal */
.jw-text p { margin: 4px 0 8px; font-family: var(--serif); line-height: 1.6; }
.jw-prompt { margin: 6px 0; font-family: var(--serif); font-style: italic; color: var(--text-dim); }
.jw-well { margin: 4px 0; font-size: .86rem; color: var(--text-dim); font-family: var(--serif); font-style: italic; }
.jw-well b { font-family: var(--sans); font-style: normal; font-size: .7rem; letter-spacing: .05em; text-transform: uppercase; color: var(--good); margin-right: 4px; }

/* Links */
.link-row { display: flex; align-items: center; gap: 6px; border-bottom: 1px solid var(--rule-soft); }
.link-item { flex: 1; display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-width: 0; padding: 9px 0; color: var(--text); text-decoration: none; }
.link-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.link-item small { flex: none; color: var(--text-faint); font-size: .74rem; }
.link-item:hover span { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.link-add { display: grid; grid-template-columns: 1fr 1.4fr auto; gap: 6px; margin-top: 8px; }
.link-add input { min-width: 0; height: 32px; padding: 0 8px; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface); outline: none; }
.link-add input:focus { border-color: var(--accent); }

/* Picker groups and miniatures */
.type-group { margin: 16px 0 8px; font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); }
.type-group:first-of-type { margin-top: 4px; }
.wp-agenda { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 5px; }
.wp-agenda > span { display: flex; align-items: center; gap: 5px; }
.wp-agenda b { flex: none; width: 12px; height: 3px; border-radius: 2px; background: var(--text-faint); }
.wp-agenda .now { height: 0; border-top: 1.5px solid var(--accent); }
.wp-next { flex-direction: column; align-items: flex-start; gap: 5px; }
.wp-next b { width: 70%; height: 6px; border-radius: 2px; background: var(--text); }
.wp-next-btns { display: flex; gap: 4px; }
.wp-next-btns .tp-input { width: 20px; flex: none; }
.wp-badge { flex: none; width: 16px; height: 6px; border-radius: 3px; background: var(--surface-2); }
.wp-badge.now { background: var(--danger); } .wp-badge.soon { background: var(--warn); }
.wp-month { flex: 1; display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; align-content: center; }
.wp-month span { aspect-ratio: 1.3; border-radius: 1px; background: var(--surface-2); }
.wp-month span.dot { background: color-mix(in srgb, var(--accent) 45%, var(--surface-2)); }
.wp-month span.today { background: var(--fill, var(--accent)); }
.wp-num { display: grid; place-items: center; flex: none; width: 9px; height: 9px; border-radius: 50%; border: 1px solid var(--rule); font-size: 5px; color: var(--text-dim); }
.wp-num.on { background: var(--good); border-color: var(--good); color: var(--bg); }
.wp-counter b { font-family: var(--serif); font-size: 1.2rem; font-weight: 400; color: var(--text); }
.wp-pm { display: grid; place-items: center; width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--rule); font-size: 9px; color: var(--text-dim); }
.wp-pm.on { background: var(--fill, var(--accent)); border-color: var(--fill, var(--accent)); color: var(--on-fill, var(--bg)); }
.wp-bar { display: block; height: 3px; border-radius: 2px; background: var(--surface-2); overflow: hidden; }
.wp-bar span { display: block; height: 100%; background: var(--good); }
.wp-note.wp-journal .tp-input { width: 100%; height: 9px; margin-top: 3px; background: var(--surface); border: 1px solid var(--rule); opacity: 1; }
.wp-link { flex: none; width: 7px; height: 7px; border-radius: 2px; border: 1px solid var(--accent); }

/* ---------- Times and task details ---------- */

.chip.time { color: var(--text); font-style: normal; font-weight: 500; font-family: var(--sans); gap: 4px; }
.chip.time svg { width: 11px; height: 11px; color: var(--accent); }
.wtime { font-weight: 600; color: var(--text-dim); font-size: .92em; }
.sheet.details-sheet { max-width: 480px; }
.td-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 12px; }
.td-grid input, .td-grid select { min-width: 0; max-width: 100%; }
/* A phone: dates and times get the room their digits need, and Priority its own line, so its
   three choices sit side by side instead of stacking. */
@media (max-width: 430px) {
    .td-grid input[type="date"], .td-grid input[type="time"] { padding: 0 8px; }
    .td-grid:has(.choice-row) { grid-template-columns: minmax(0, 1fr); }
}
.task-details textarea {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    font: inherit;
    resize: vertical;
    outline: none;
}
.task-details textarea:focus { border-color: var(--accent); }
.task-details select { width: 100%; height: var(--tap); padding: 0 10px; border: 1px solid var(--rule);
    border-radius: var(--radius); background: var(--surface); outline: none; }

/* ---------- Connections (MCP) ---------- */


/* ---------- Accounts, consent ---------- */

.danger-zone { margin-top: 44px; }

/* ---------- Style tab ---------- */

/* Controls on the left, a small live piece of the app on the right that
   stays in view while scrolling, so type and shape can be judged. */
.style-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    max-width: 1120px;
    margin: 0 auto;
}
.style-sample { order: -1; pointer-events: none; }
.colour-map { order: -1; }
@media (min-width: 900px) {
    .style-layout { grid-template-columns: minmax(0, 1fr) 300px; gap: 36px; align-items: start; }
    .style-sample, .colour-map { order: 0; position: sticky; top: 140px; margin-top: 30px; }
}
@media (max-width: 899px) {
    /* On a phone the sample is a reminder, not a second page. */
    .style-sample .sample-capture { display: none; }
    .style-sample .task:nth-child(3) { display: none; }
}
/* The parts of the look, one at a time: a segmented strip, so it reads as a
   level below the app's own tabs, and all fit a phone without scrolling. */
.style-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2px;
    padding: 3px;
    margin: 4px 0 22px;
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 3px);
    background: var(--surface);
}
.style-tabs button {
    border: 0;
    border-radius: var(--radius);
    background: none;
    color: var(--text-dim);
    padding: 8px 4px;
    font-size: .88rem;
    font-weight: 500;
    white-space: nowrap;
    transition: color .15s, background-color .15s;
}
.style-tabs button:hover { color: var(--text); }
.style-tabs button[aria-selected="true"] {
    background: var(--fill, var(--accent));
    color: var(--on-fill, var(--surface));
}
.style-pane .section:first-child { margin-top: 0; }
.style-reset { display: flex; align-items: center; flex-wrap: wrap; row-gap: 8px; }
.colour-reset { margin-top: 14px; }

/* The Style tab, one column: the themes on top, the three tabs for
   fine-tuning beneath, each tab with its own preview at its head. */
.style-layout.solo { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
.style-themes { margin-top: 4px; }
.style-themes .section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.style-now { font-family: var(--serif); font-style: italic; font-size: .88rem; color: var(--text-dim); }
.style-themes + .style-custom { margin-top: 26px; }
.style-custom .acc-body { padding-top: 6px; }
.style-custom .style-tabs { margin-top: 0; }
@media (max-width: 899px) {
    /* Pinned inside the Custom card, edge to edge within it. */
    .style-custom .colour-map { margin: 0 -14px; padding: 8px 14px 2px; background: var(--surface); }
}
.pane-sample { margin-bottom: 18px; }
.pane-sample .sample-capture, .pane-sample .task:nth-child(3) { display: none; }
@media (max-width: 899px) {
    /* The kinds of theme run to the screen's edges, so it is plain they scroll. */
    .theme-chips { margin: 0 -16px 14px; padding: 0 16px 2px; }
}
@media (min-width: 900px) {
    .solo .style-sample { position: static; margin-top: 0; }
    .solo .colour-map { top: 120px; z-index: 5; max-width: 420px; margin: 0 auto 16px; padding-top: 6px; background: var(--bg); }
}

/* Colours: Themes and Custom, sections that open one at a time. */
.acc-list { display: flex; flex-direction: column; gap: 10px; }
.acc { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface); }
.acc-head {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 14px;
    border: 0;
    background: none;
    color: var(--text);
    text-align: left;
    cursor: pointer;
}
.acc-title { font-weight: 500; font-size: 1rem; }
.acc-now { margin-left: auto; font-family: var(--serif); font-style: italic; font-size: .86rem; color: var(--text-dim); }
.acc-chev { flex: none; width: 16px; height: 16px; color: var(--text-dim); transition: transform .2s; }
.acc.open .acc-chev { transform: rotate(90deg); }
.acc-body { padding: 2px 14px 16px; }
.acc-body .layer-list { background: var(--bg); }

/* Themes: the kinds of theme as one sideways-scrolling row, then the open
   kind's themes as colour tiles: the page, a card on it, the accent. */
.theme-chips {
    display: flex;
    gap: 6px;
    margin: 0 0 14px;
    padding: 0 0 2px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}
.theme-chips::-webkit-scrollbar { display: none; }
.theme-chips button {
    flex: none;
    padding: 5px 12px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: none;
    color: var(--text-dim);
    font-size: .82rem;
    white-space: nowrap;
    transition: color .15s, background-color .15s, border-color .15s;
}
.theme-chips button:hover { color: var(--text); }
.theme-chips button[aria-pressed="true"] { background: var(--fill, var(--accent)); border-color: var(--fill, var(--accent)); color: var(--on-fill, var(--surface)); }

.tsw-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 12px; }
@media (min-width: 600px) { .tsw-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); } }
.tsw-slot { position: relative; }
.tswatch {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.tsw-tile {
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    overflow: hidden;
    border: 1px solid var(--r);
    border-radius: 12px;
    background: linear-gradient(135deg, var(--b1) 50%, var(--b2) 50%);
    transition: box-shadow .2s;
}
.tsw-card {
    position: absolute;
    inset: 18% 14% 30%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 16%;
    padding: 0 11%;
    border: 1px solid var(--r);
    border-radius: 5px;
    background: linear-gradient(135deg, var(--s1) 50%, var(--s2) 50%);
}
/* Two lines of "text" in the theme's text colour, so legibility shows. */
.tsw-row { display: flex; align-items: center; gap: 8%; }
.tsw-line { flex: 1; height: 3px; border-radius: 2px; background: linear-gradient(135deg, var(--t1) 50%, var(--t2) 50%); }
.tsw-line.short { flex: .62; opacity: .7; }
/* Its urgent and late colours, as the little marks they are in a task list. */
.tsw-mark { flex: none; width: 22%; height: 5px; border-radius: 3px; }
.tsw-mark.urgent { background: linear-gradient(135deg, var(--d1) 50%, var(--d2) 50%); }
.tsw-mark.late { background: linear-gradient(135deg, var(--w1) 50%, var(--w2) 50%); }
.tsw-row:has(.short) { justify-content: space-between; }
.tsw-dot { position: absolute; right: 13%; bottom: 10%; width: 20%; height: 20%; border-radius: 50%; background: var(--a); }
.tsw-name { max-width: 100%; font-size: .76rem; line-height: 1.2; text-align: center; color: var(--text-dim); overflow-wrap: anywhere; }
.tswatch[aria-pressed="true"] .tsw-tile { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent); }
.tswatch[aria-pressed="true"] .tsw-name { color: var(--text); font-weight: 600; }
@media (hover: hover) {
    .tswatch:hover:not([aria-pressed="true"]) .tsw-tile { box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--accent) 55%, transparent); }
}
.tsw-edit {
    position: absolute;
    top: 4px;
    right: 4px;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-dim);
}
.tsw-edit svg { width: 12px; height: 12px; }

/* The Colours tab's picture of the app: painted with the real colour
   variables, so it changes live; each part is tagged with the layer that
   paints it. Choosing a layer spotlights it: a veil the colour of the page
   fades everything else back, and the chosen part sits above the veil. */
.colour-map { align-self: start; }
@media (max-width: 899px) {
    /* Pinned under the top bar, so it stays in view while the colours below
       are scrolled through and changed. */
    .colour-map { position: sticky; top: calc(60px + env(safe-area-inset-top, 0px)); z-index: 5; margin: 0 -16px; padding: 8px 16px 2px; background: var(--bg); }
}
.cm-frame {
    position: relative;
    z-index: 0;
    background: var(--bg);
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 4px);
    padding: 10px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .07);
}
.colour-map [data-layer] { cursor: pointer; }
.cm-card { display: block; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius); padding: 6px 10px; }
.cm-rule { display: block; height: 9px; background: linear-gradient(var(--rule), var(--rule)) center / 100% 1px no-repeat; }
.cm-row { display: flex; align-items: center; gap: 8px; min-height: 22px; font-size: .82rem; }
.cm-check { flex: none; width: 14px; height: 14px; border: 1.5px solid var(--text-faint); border-radius: 50%; }
.cm-check.done { display: grid; place-items: center; background: var(--good); border-color: var(--good); color: var(--surface); }
.cm-check.done svg { width: 9px; height: 9px; }
.cm-task { flex: 1; min-width: 0; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cm-task.done { color: var(--text-faint); text-decoration: line-through; }
.cm-chip { font-family: var(--serif); font-size: .72rem; font-weight: 600; font-style: italic; }
.cm-chip[data-layer="danger"] { color: var(--danger); }
.cm-chip[data-layer="warn"] { color: var(--warn); }
.cm-capture { display: flex; gap: 6px; margin-top: 8px; }
.cm-input {
    flex: 1;
    display: flex;
    align-items: center;
    height: 28px;
    padding: 0 9px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
    font-size: .78rem;
}
.cm-btn { display: flex; align-items: center; padding: 0 12px; border-radius: var(--radius); background: var(--fill, var(--accent)); color: var(--on-fill, var(--surface)); font-size: .8rem; font-weight: 500; }

/* The spotlight. */
.cm-frame::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: color-mix(in srgb, var(--bg) 72%, transparent);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
}
.colour-map[data-spot]:not([data-spot=""]):not([data-spot="bg"]) .cm-frame::after { opacity: 1; }
.colour-map .cm-on { position: relative; z-index: 2; }
/* The card: what sits on it in other layers' colours (the lines, its own
   border, and the urgent, late and done marks) stays back while the card
   is chosen or previewed, so only the card itself reads as chosen. */
.colour-map[data-spot="surface"] .cm-card .cm-rule { opacity: .2; }
.colour-map[data-spot="surface"] .cm-card :is(.cm-chip, .cm-check.done) { opacity: .25; }
.colour-map[data-spot="surface"] .cm-card.cm-on { border-color: color-mix(in srgb, var(--rule) 25%, var(--surface)); }
@media (hover: hover) {
    .colour-map[data-spot]:not([data-spot=""]):not([data-spot="surface"]) .cm-card:hover:not(:has([data-layer]:hover)) .cm-rule { opacity: .2; }
    .colour-map[data-spot]:not([data-spot=""]):not([data-spot="surface"]) .cm-card:hover:not(:has([data-layer]:hover)) :is(.cm-chip, .cm-check.done) { opacity: .25; }
    .colour-map[data-spot]:not([data-spot=""]):not([data-spot="surface"]) .cm-card:hover:not(:has([data-layer]:hover)) {
        border-color: color-mix(in srgb, var(--rule) 25%, var(--surface));
    }
}
/* And the other way round: Lines brings forward every line it paints, the
   card's border and the writing box's outline too, while their fill and
   words stay faded. */
.colour-map[data-spot="rule"] :is(.cm-card, .cm-input) {
    position: relative;
    z-index: 2;
    background: color-mix(in srgb, var(--surface) 30%, transparent);
}
.colour-map[data-spot="rule"] .cm-card :is(.cm-row) { opacity: .3; }
.colour-map[data-spot="rule"] .cm-input { color: transparent; }
.cm-rule, .cm-chip, .cm-check { transition: opacity .2s, filter .2s; }
.cm-card { transition: box-shadow .2s, border-color .2s; }

/* The page itself: its contents fade instead, and the page keeps its colour. */
.colour-map[data-spot="bg"] .cm-card, .colour-map[data-spot="bg"] .cm-capture { opacity: .28; transition: opacity .2s; }
/* A soft underglow in the accent colour: a hint on hover of what a tap would
   choose, a little stronger on the chosen part. Boxes glow beneath; words,
   labels and lines glow around their own shape, so nothing is outlined.
   Only the innermost part under the pointer glows. */
.colour-map [data-layer] { transition: box-shadow .2s, filter .2s; }
.cm-card.cm-on, .cm-btn.cm-on, .cm-frame.cm-on {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent),
                0 8px 22px -6px color-mix(in srgb, var(--accent) 65%, transparent);
}
.cm-task.cm-on, .cm-chip.cm-on, .cm-check.cm-on, .cm-rule.cm-on {
    filter: drop-shadow(0 2px 5px color-mix(in srgb, var(--accent) 70%, transparent));
}
@media (hover: hover) {
    .colour-map [data-layer]:hover:not(:has([data-layer]:hover)):not(.cm-frame) { position: relative; z-index: 2; }
    :is(.cm-card, .cm-btn, .cm-frame):hover:not(:has([data-layer]:hover)):not(.cm-on) {
        box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--accent) 50%, transparent);
    }
    :is(.cm-task, .cm-chip, .cm-check, .cm-rule)[data-layer]:hover:not(.cm-on) {
        filter: drop-shadow(0 2px 4px color-mix(in srgb, var(--accent) 55%, transparent));
    }
}
.cm-caption { margin: 6px 2px 4px; text-align: center; font-size: .8rem; color: var(--text-dim); }
.cm-caption b { color: var(--text); font-weight: 600; }

/* Each layer: its colour, its name, and where it shows. */
.layer-list { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.layer-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px; cursor: pointer; transition: background-color .15s; }
.layer-row + .layer-row { border-top: 1px solid var(--rule); }
.layer-row.on { background: color-mix(in srgb, var(--accent) 9%, var(--surface)); }
.layer-pick { flex: none; }
.layer-pick input[type="color"] {
    -webkit-appearance: none;
    appearance: none;
    width: 36px;
    height: 36px;
    padding: 2px;
    border: 1px solid var(--rule);
    border-radius: 9px;
    background: var(--surface);
    cursor: pointer;
}
.layer-pick input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.layer-pick input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 6px; }
.layer-pick input[type="color"]::-moz-color-swatch { border: 0; border-radius: 6px; }
.layer-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.layer-name { font-weight: 500; color: var(--text); }
.layer-where { font-family: var(--serif); font-style: italic; font-size: .82rem; color: var(--text-dim); }
.layer-row code { align-self: center; font-size: .74rem; color: var(--text-faint); }
.accent-layer .accent-row { margin-top: 9px; }

.style-hint { margin: -4px 0 12px; font-size: .84rem; color: var(--text-dim); font-family: var(--serif); font-style: italic; }
.style-hint.inline { margin: 0 0 0 10px; }

.sample-panel .panel-head { cursor: default; }
.sample-panel .task-title { font-size: 1rem; }
.sample-capture { display: flex; gap: 8px; margin-top: 12px; }
.sample-input {
    flex: 1;
    display: flex;
    align-items: center;
    height: var(--tap);
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
}
.sample-capture .btn { display: inline-flex; align-items: center; }

/* The schedule: a card per time of day or season. The selected one is what
   the theme grid below is choosing for. */
.schedule { margin: 4px 0 20px; }
.slot-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.slot { display: flex; flex-direction: column; gap: 6px; }
.slot-pick {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 6px 6px 8px;
    text-align: left;
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 2px);
    background: var(--surface);
    color: var(--text);
}
.slot-pick:hover { border-color: var(--text-faint); }
.slot-pick[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.slot-label { display: flex; align-items: baseline; gap: 6px; padding: 0 3px; font-size: .86rem; font-weight: 500; }
.slot-label em {
    font-style: normal;
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--accent);
}
.slot-theme { padding: 0 3px; font-size: .78rem; color: var(--text-dim); }
.slot-time { display: flex; align-items: center; gap: 6px; font-size: .8rem; color: var(--text-dim); }
.slot-time input {
    flex: 1;
    min-width: 0;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
}
.slot-hemi { margin-top: 12px; }

.theme-group + .theme-group { margin-top: 18px; }
.theme-filter { margin: -2px 0 14px; row-gap: 6px; }
.theme-filter .count { margin-left: 4px; font-size: .72rem; color: var(--text-faint); }
.group-title {
    margin: 0 0 8px;
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.theme-slot { position: relative; display: flex; }
.theme-slot .theme-card { flex: 1; min-width: 0; }
.theme-edit {
    position: absolute;
    top: 10px;
    right: 10px;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-dim);
}
.theme-edit:hover { color: var(--text); border-color: var(--text-faint); }
.theme-edit svg { width: 13px; height: 13px; }
.theme-card.new { border-style: dashed; }
.new-preview {
    align-items: center;
    justify-content: center;
    background: var(--bg);
    color: var(--text-faint);
    font-size: 1.6rem;
    font-weight: 300;
}
.theme-name small { display: block; font-size: .72rem; color: var(--text-faint); }
.theme-card.new .theme-name { display: block; }
.theme-name { align-items: flex-start; }

.theme-editor { margin-top: 12px; padding: 16px; }
.editor-title { margin: 0; font-family: var(--serif); font-size: 1.05rem; font-weight: 500; }
.editor-sub { margin: 2px 0 14px; font-size: .84rem; color: var(--text-dim); font-family: var(--serif); font-style: italic; }
.color-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 8px;
}
.color-field {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    column-gap: 10px;
    align-items: center;
    padding: 7px 9px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
}
.color-field input {
    grid-row: 1 / 3;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    background: none;
    cursor: pointer;
}
.color-field input::-webkit-color-swatch-wrapper { padding: 2px; }
.color-field input::-webkit-color-swatch { border: 0; border-radius: 2px; }
.color-field input::-moz-color-swatch { border: 0; border-radius: 2px; }
.color-label { font-size: .86rem; }
.color-field code { font-size: .74rem; color: var(--text-faint); }
.editor-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--rule-soft);
}
.editor-actions .spacer { flex: 1; }
.btn.warn-text { color: var(--danger); }

/* The accent row: "the theme's own" is drawn half light, half dark, since
   what it gives depends on the theme; "any colour" is a swatch-shaped picker. */
.accent-row { align-items: center; }
.swatch.own { background: linear-gradient(135deg, var(--own-l) 50%, var(--own-d) 50%); }
.swatch.custom {
    display: grid;
    place-items: center;
    overflow: hidden;
    cursor: pointer;
    background: conic-gradient(#c24e25, #c9a227, #4a7a5f, #2f7a8a, #5f4463, #9d3f2c, #c24e25);
}
.swatch.custom.on { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--text-dim); }
.swatch.custom input { opacity: 0; width: 100%; height: 100%; cursor: pointer; border: 0; padding: 0; }
.swatch.custom:focus-within { outline: 2px solid var(--accent); outline-offset: 3px; }

.font-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 8px;
}
.font-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 10px 6px 8px;
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 2px);
    background: var(--surface);
    color: var(--text-dim);
}
.font-card:hover { border-color: var(--text-faint); }
.font-card[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); color: var(--text); }
.font-sample { font-size: 1.7rem; line-height: 1.1; color: var(--text); }
.font-name { font-size: .76rem; }

.choice-row button span { vertical-align: middle; }
.corner-demo {
    display: inline-block;
    width: 16px;
    height: 12px;
    margin-right: 7px;
    border: 1.5px solid currentColor;
}

/* ---------- Visual widgets ---------- */

/* Progress dial: one number, one arc. The whole point is that you read it in
   a glance without parsing a sentence. */
.dial { display: flex; align-items: center; justify-content: center; padding: 14px 0 6px; }
.dial svg { width: 132px; height: 132px; transform: rotate(-90deg); }
.dial .track { stroke: var(--rule); }
.dial .fill {
    stroke: var(--accent);
    stroke-linecap: round;
    transition: stroke-dashoffset .5s cubic-bezier(.4, 0, .2, 1);
}
.dial-label {
    position: absolute;
    text-align: center;
    pointer-events: none;
}
.dial-wrap { position: relative; display: grid; place-items: center; }
.dial-num {
    font-family: var(--serif);
    font-size: 2.1rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.dial-sub {
    font-size: .74rem;
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
    margin-top: 3px;
}

/* Habit rings: one ring each, filled by the week's progress, streak inside. */
.rings { display: flex; flex-wrap: wrap; gap: 14px; padding: 12px 0 6px; justify-content: center; }
.ring-item { display: block; border: 0 !important; padding: 0 !important; text-align: center; }
.ring-btn {
    border: 0;
    background: none;
    padding: 0;
    position: relative;
    display: grid;
    place-items: center;
    transition: transform .12s;
}
.ring-btn:active { transform: scale(.93); }
.ring-btn svg { width: 62px; height: 62px; transform: rotate(-90deg); }
.ring-btn .track { stroke: var(--rule); }
.ring-btn .fill { stroke-linecap: round; transition: stroke-dashoffset .4s ease; }
.ring-centre {
    position: absolute;
    font-size: .95rem;
    font-family: var(--serif);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.ring-item.done .ring-centre { color: var(--text); }
.ring-item:not(.done) .ring-centre { color: var(--text-faint); }
.ring-name {
    display: block;
    font-size: .7rem;
    color: var(--text-dim);
    margin-top: 5px;
    max-width: 74px;
    line-height: 1.25;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* Heatmap: twelve weeks, no words at all. */
.heat {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(7, 1fr);
    gap: 3px;
    padding: 12px 0 6px;
}
.heat i {
    aspect-ratio: 1;
    border-radius: 2px;
    background: var(--rule-soft);
    display: block;
}
.heat i[data-level="1"] { background: color-mix(in srgb, var(--accent) 28%, var(--rule-soft)); }
.heat i[data-level="2"] { background: color-mix(in srgb, var(--accent) 52%, var(--rule-soft)); }
.heat i[data-level="3"] { background: color-mix(in srgb, var(--accent) 76%, var(--rule-soft)); }
.heat i[data-level="4"] { background: var(--fill, var(--accent)); }
.heat i.today { outline: 1.5px solid var(--warn); outline-offset: 1px; }

.heat-legend {
    display: flex;
    align-items: center;
    gap: 5px;
    justify-content: flex-end;
    font-size: .7rem;
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
}
.heat-legend i { width: 9px; height: 9px; border-radius: 2px; display: block; }

/* A single big number, for when a count is all you need. */
.bignum {
    text-align: center;
    padding: 16px 0 10px;
}
.bignum b {
    display: block;
    font-family: var(--serif);
    font-size: 3rem;
    line-height: 1;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}
.bignum span {
    display: block;
    margin-top: 6px;
    font-size: .8rem;
    color: var(--text-dim);
    font-family: var(--serif);
    font-style: italic;
}
.bignum.quiet b { color: var(--text-faint); }

/* Countdown reuses the big number with its own unit line. */
.countdown-date {
    text-align: center;
    font-size: .74rem;
    color: var(--text-faint);
    font-family: var(--serif);
    font-style: italic;
    padding-bottom: 8px;
}

/* Compact task list: titles only, nothing else. */
.tasks-compact .task { padding-top: 6px; padding-bottom: 6px; border-bottom: 0; }
.tasks-compact .task-meta { display: none; }
.tasks-compact .task-actions { display: none; }
.tasks-compact .check { width: 16px; height: 16px; margin-top: 3px; }
.tasks-compact .task-title { font-size: .92rem; }

/* ---------- Panel style ---------- */

/* Plain: no boxes at all, just space and a rule under each title. */
:root[data-panels="plain"] .panel {
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0 0 6px;
}
:root[data-panels="plain"] .panel[data-accent] { border: 0; }

/* Soft: no outline, a gentle tint instead — quieter than a bordered card. */
:root[data-panels="soft"] .panel {
    background: color-mix(in srgb, var(--text) 4%, var(--bg));
    border-color: transparent;
}
:root[data-panels="soft"] .panel[data-accent] {
    background: color-mix(in srgb, var(--w) 8%, var(--bg));
    border-color: transparent;
}

/* What sits underneath a panel's contents, so the controls that float over
   rows can mask the text beneath them in every panel style. */
.panel { --under: var(--surface); }
:root[data-panels="plain"] .panel { --under: var(--bg); }
:root[data-panels="soft"] .panel { --under: color-mix(in srgb, var(--text) 4%, var(--bg)); }
:root[data-panels="soft"] .panel[data-accent] { --under: color-mix(in srgb, var(--w) 8%, var(--bg)); }

/* ---------- Weight ---------- */

/* The widest widgets are the ones you read first, so their type is a size
   larger and their rows breathe more. Hierarchy has to be visible. */
@container (min-width: 520px) {
    .panel-body .task-title { font-size: 1.04rem; }
    .panel-body .task { padding-top: 13px; padding-bottom: 13px; }
}

/* The header is the date, so it should carry like one. */
.greeting { font-size: 2.1rem; letter-spacing: -.015em; }
.datestamp { font-size: 1rem; }

@media (max-width: 430px) {
    .greeting { font-size: 1.7rem; }
}

/* ---------- The board: a grid of cells, like a phone's home screen ---------- */

/*
 * The board measures itself (a container query, not the window), so the
 * same layout works in a phone, a tablet, a desktop window of any width, and
 * the app. Every widget says how many twelfths wide it is (--w12) and what
 * that comes to on 8 and 4 cells (--w8, --w4); rows are square-ish cells,
 * and "dense" packing slots small things into the gaps big ones leave.
 * gridMetrics() in app.js mirrors these numbers.
 */
.board-bar { display: flex; justify-content: flex-end; min-height: 20px; margin: 16px 0 6px; }
.board-edit { font-size: .8rem; color: var(--text-faint); }
.board-edit:hover { color: var(--accent); }
.board-wrap { container: board / inline-size; }
.board {
    --n: 12;
    --gap: 16px;
    --row: clamp(64px, calc((100cqw - (var(--n) - 1) * var(--gap)) / var(--n)), 96px);
    display: grid;
    gap: var(--gap);
    grid-template-columns: repeat(var(--n), minmax(0, 1fr));
    grid-auto-rows: var(--row);
    grid-auto-flow: row dense;
}
.board > .tile { grid-column: span var(--w12, 4); grid-row: span var(--h, 3); }
@container board (max-width: 999.98px) {
    .board { --n: 8; }
    .board > .tile { grid-column: span var(--w8, 4); }
}
@container board (max-width: 599.98px) {
    .board { --n: 4; --gap: 12px; }
    .board > .tile { grid-column: span var(--w4, 4); }
}

/* A widget fills its block of cells; a set height scrolls inside, a fitted
   one was measured to hold everything. */
.board > .panel {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 0;
    container-type: inline-size;
}
.board > .panel > .panel-head { flex: none; }
.board > .panel > .panel-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}
.board > .panel.fit > .panel-body { overflow: visible; }
.board > .tile.measuring { grid-row: span 1 !important; align-self: start; }

/* Small widgets say less: the count and the name, not the whole sentence. */
@container (max-width: 250px) {
    .panel-note { display: none; }
    .panel-body .task-meta { display: none; }
    .panel-body .task-actions { display: none; }
    .panel-title { font-size: .95rem; }
}
@container (max-width: 180px) {
    .bignum b { font-size: 2rem; }
}

/* ---------- Two rows high or less: everything fits, nothing scrolls ----------
   A short widget keeps its title and loses the extras: one line per item,
   charts sized to the room there is, and a list that is still too long shows
   what fits and "+N more" (clipTiles in app.js), which opens it up in place.
   The body is a size container, so a chart can size itself by its height. */
.board > .panel.short { padding: 9px 12px 10px; }
.board > .panel.short > .panel-head { padding-bottom: 4px; margin-bottom: 3px; }
.board > .panel.short .panel-title { font-size: .93rem; }
.board > .panel.short > .panel-body { overflow: hidden; container-type: size; }
/* Lists (tasks, habits and the like) scroll in their box instead. */
.board > .panel.short.scrolls > .panel-body { overflow-y: auto; }
.board > .panel.short .clip-hidden { display: none !important; }

.tile-more {
    display: block;
    margin: 1px 0 0;
    padding: 2px 0;
    border: 0;
    background: none;
    font-size: .78rem;
    font-weight: 500;
    color: var(--accent);
    cursor: pointer;
}
.tile-more:hover { text-decoration: underline; text-underline-offset: 3px; }
.panel.expanded [data-tile-less] { margin-top: 8px; }
.board.editing .tile-more { visibility: hidden; }
.widget-foot > .tile-more { margin: 0; padding: 0; }
.rings > .tile-more { flex-basis: 100%; text-align: center; }

/* Lists: one line each, the details left for when it is opened up. */
.short .task, .short .habit, .short .rule, .short .shared-row { padding-top: 5px; padding-bottom: 5px; gap: 10px; }
.short .task { align-items: center; }
.short .task-meta, .short .task-actions, .short .done-fold { display: none; }
.short .task-title, .short .habit-name, .short .rule-name {
    font-size: .92rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.short .check { width: 16px; height: 16px; margin-top: 0; }
.short .habit-tick { width: 20px; height: 20px; }
.short .habit-tick svg { width: 11px; height: 11px; }
.short .habit-body, .short .rule-body { display: flex; align-items: baseline; gap: 8px; }
.short .habit-name, .short .rule-name { flex: 0 1 auto; min-width: 0; }
.short .habit-sub, .short .rule-sub {
    flex: 0 1 auto;
    min-width: 0;
    margin: 0;
    font-size: .76rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@container (max-width: 240px) {
    .short .habit-sub, .short .rule-sub { display: none; }
    /* Narrow: the name before the address, the title before the tick. */
    .short .link-item small { display: none; }
    .short .dl .check { display: none; }
    .short .dl-badge { padding: 1px 5px; font-size: .66rem; }
}
.short .upcoming-day { margin: 3px 0 0; font-size: .74rem; }
.short .upcoming-day:first-child { margin-top: 0; }
.short .ag-time { padding-top: 6px; }
.short .ag-any { margin-top: 4px; }
.short .dl { gap: 8px; align-items: center; }
.short .cl-item label { padding: 4px 0; }
.short .link-item { padding: 5px 0; }
.short .three { gap: 2px; padding: 0; }
.short .three-item { padding: 3px 2px; font-size: .92rem; }
.short .three-box { width: 20px; height: 20px; }
.short .widget-add { margin-top: 2px; }
.short .widget-add input { height: 28px; }
.short .widget-foot { flex-wrap: wrap; gap: 2px 12px; padding-top: 4px; border-top: 0; }
.short .widget-foot > * { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.short .empty { padding: 6px 2px; }

/* Charts and counters: sized to the height there is. */
.short .dial { height: 100%; padding: 0; }
.short .dial svg { width: min(132px, 100cqh); height: min(132px, 100cqh); }
.short .dial-num { font-size: clamp(1.2rem, 25cqh, 2.1rem); }
.short .dial-sub { margin-top: 1px; }

.short .rings { gap: 6px 8px; padding: 2px 0 0; }
.short .ring-btn svg { width: min(62px, calc(100cqh - 24px)); height: min(62px, calc(100cqh - 24px)); }
.short .ring-name { max-width: 64px; margin-top: 3px; -webkit-line-clamp: 1; }

/* Heatmap: squares sized by the height; when the weeks do not all fit
   across, the oldest give way (the newest stay at the right). */
.short .panel-body:has(> .heat) { display: flex; flex-direction: column; align-items: flex-end; }
.short .heat {
    --cell: calc((100cqh - 2px - 6 * 3px) / 7);
    flex: none;
    margin-inline: auto;
    padding: 2px 0 0;
    grid-template-rows: repeat(7, var(--cell));
    grid-auto-columns: var(--cell);
}
.short .heat i { aspect-ratio: auto; }
.short .heat-legend { display: none; }

.short .bignum { padding: 4px 0 0; }
.short .counter { padding: 0; }
.short .counter-num b { font-size: 1.9rem; }
.short .counter-bar { margin: 8px 0 0; }
.short .counter-week { display: none; }
.short .timer { padding: 0; }
.short .timer-clock { margin: 2px 0 6px; font-size: clamp(1.6rem, 32cqh, 2.6rem); }
.short .timer-sub { display: none; }
.short .next { padding: 0; }
.short .next-title {
    margin: 2px 0 0;
    font-size: 1.05rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.short .next-meta { display: none; }
.short .next-actions { margin-top: 8px; }

/* The month: its name and the week holding today. */
.short .mo-head { margin: 0 0 4px; }
.short .mo-grid > :not(.mo-wd):not(.wk-now) { display: none; }
.short .mo-day { padding: 2px 0; }

/* This week's three, still to set: the three boxes, the button beside the last. */
.short .three-set { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 6px; }
.short .three-set .empty { display: none; }
.short .three-set input { grid-column: 1 / -1; height: 28px; }
.short .three-set input:nth-of-type(3) { grid-column: 1; }
.short .three-set .btn { grid-column: 2; align-self: stretch; margin: 0; }
@container (max-width: 240px) {
    .short .three-set { gap: 3px; }
    .short .three-set input { height: 26px; }
    .short .three-set input:nth-of-type(3), .short .three-set .btn { grid-column: 1 / -1; }
    .short .three-set .btn { justify-self: start; }
}

/* The journal: as much of today's page as fits, fading out, then the line to add to it. */
.short .jw { display: flex; flex-direction: column; height: 100%; }
.short .jw-text {
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(#000 calc(100% - 1.4em), transparent);
    mask-image: linear-gradient(#000 calc(100% - 1.4em), transparent);
}
.short .jw-text p { margin: 0 0 4px; line-height: 1.45; }
.short .jw-prompt { margin: 0; }
.short .jw-well { display: none; }
.short .jw > .widget-add, .short .jw > .widget-foot { flex: none; }

/* ---------- Apps ---------- */

.board > .tile.app {
    container-type: normal;
    background: none;
    border: 0;
    padding: 0;
    box-shadow: none;
    display: flex;
    align-items: center;
    justify-content: center;
}
.app-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: 100%;
    height: 100%;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--text);
    font: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}
.app-icon {
    position: relative;
    display: grid;
    place-items: center;
    width: clamp(38px, calc(var(--row, 76px) - 32px), 60px);
    aspect-ratio: 1;
    border-radius: 27%;
    background: var(--w, var(--accent));
    color: var(--surface);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--text) 18%, transparent);
    transition: scale .12s ease, filter .12s ease;
}
.app-icon svg { width: 48%; height: 48%; }
.app-btn:hover .app-icon { filter: brightness(1.07); }
.app-btn:active .app-icon { scale: .92; }
.app-btn:focus-visible { outline: none; }
.app-btn:focus-visible .app-icon { outline: 2px solid var(--accent); outline-offset: 3px; }
.app-badge {
    position: absolute;
    top: -6px;
    right: -7px;
    min-width: 19px;
    height: 19px;
    padding: 0 5px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: var(--danger);
    color: var(--on-danger, #fff);
    font-size: .68rem;
    font-weight: 600;
    line-height: 1;
    box-shadow: 0 0 0 2px var(--bg);
}
.app-name {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .74rem;
    color: var(--text-dim);
}
.tile.app.untitled .app-name { display: none; }

/* In the picker: the icon on its own, smaller cards. */
.type-grid.apps { grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); }
.type-card.app-card .type-preview { height: 64px; }
.tp-app { flex: 1; display: grid; place-items: center; }
.tp-app .app-icon { width: 42px; --row: 74px; }
@media (hover: hover) {
    .type-card.app-card .type-desc { height: 64px; }
}

/* ---------- Edit mode ---------- */

/* Widgets wobble, as a phone's icons do, so it is obvious that they can be
   moved, and nothing inside them can be pressed by accident. */
.board.editing .tile { cursor: grab; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.board.editing .tile > :not(.edit-chrome) { pointer-events: none; }
.board.editing .tile { animation: tile-wobble .28s ease-in-out infinite alternate; }
.board.editing .tile:nth-child(2n) { animation-delay: -.14s; animation-duration: .31s; }
.board.editing .tile:nth-child(3n) { animation-delay: -.07s; }
.board.editing .tile.app { animation-name: app-wobble; }
@keyframes tile-wobble { from { rotate: -.35deg; } to { rotate: .35deg; } }
@keyframes app-wobble { from { rotate: -2deg; } to { rotate: 2deg; } }
@media (prefers-reduced-motion: reduce) {
    .board.editing .tile { animation: none; outline: 1px dashed var(--text-faint); outline-offset: 3px; }
}
.board.editing .tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; animation-play-state: paused; }
.board.editing .tile.armed,
.board.editing .tile.resizing { animation: none; }
.board .tile.resizing { outline: 2px solid var(--accent); outline-offset: 2px; z-index: 5; }
.board .tile.placeholder { opacity: .22; animation: none; }
.board .tile.just-added { animation: tile-arrive .6s ease-out; }
@keyframes tile-arrive { from { scale: .85; opacity: 0; } }

/* The widget being dragged, following the finger. */
.tile-ghost {
    position: fixed;
    z-index: 1000;
    margin: 0;
    pointer-events: none;
    scale: 1.04;
    opacity: .95;
    box-shadow: 0 18px 44px color-mix(in srgb, var(--text) 28%, transparent);
    rotate: 1deg;
}
.tile-ghost.panel { display: flex; flex-direction: column; overflow: hidden; }
.tile-ghost.panel .panel-body { flex: 1; min-height: 0; overflow: hidden; }
.tile-ghost.app { display: flex; align-items: center; justify-content: center; background: none; border: 0; box-shadow: none; }

.edit-chrome { position: absolute; inset: 0; pointer-events: none; z-index: 4; }
.edit-chrome > * { pointer-events: auto; }
.ec-away, .ec-gear {
    position: absolute;
    top: -9px;
    width: 26px;
    height: 26px;
    padding: 0;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid var(--rule);
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 2px 6px color-mix(in srgb, var(--text) 18%, transparent);
    font-size: 18px;
    line-height: 1;
}
.ec-away { left: -9px; }
.ec-gear { right: -9px; }
.ec-gear svg { width: 14px; height: 14px; }
.ec-away:hover { color: var(--danger); }
.ec-gear:hover { color: var(--accent); }
.tile.app .ec-away { left: 2px; top: -4px; }

.ec-size {
    position: absolute;
    left: 50%;
    bottom: 8px;
    translate: -50% 0;
    padding: 3px 11px;
    border: 0;
    border-radius: 999px;
    background: var(--text);
    color: var(--bg);
    font-size: .72rem;
    font-weight: 500;
    white-space: nowrap;
    opacity: .88;
}
.ec-size:hover { opacity: 1; }
.ec-resize {
    position: absolute;
    right: -6px;
    bottom: -6px;
    width: 26px;
    height: 26px;
    cursor: nwse-resize;
    touch-action: none;
}
.ec-resize::after {
    content: "";
    position: absolute;
    right: 5px;
    bottom: 5px;
    width: 12px;
    height: 12px;
    border-right: 3px solid var(--accent);
    border-bottom: 3px solid var(--accent);
    border-bottom-right-radius: 6px;
}
@media (pointer: coarse) {
    .ec-resize { width: 36px; height: 36px; right: -10px; bottom: -10px; }
    .ec-resize::after { right: 9px; bottom: 9px; }
}

/* Done, and Add, where the capture bar usually is. */
.edit-bar {
    position: fixed;
    left: 50%;
    translate: -50% 0;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px;
    max-width: calc(100vw - 24px);
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 999px;
    box-shadow: 0 10px 30px color-mix(in srgb, var(--text) 20%, transparent);
}
.edit-bar .btn { height: 36px; border-radius: 999px; }
.edit-hint { font-family: var(--serif); font-style: italic; font-size: .8rem; color: var(--text-faint); white-space: nowrap; }
@media (max-width: 480px) { .edit-hint { display: none; } }
body.board-editing .capture { visibility: hidden; }

.board-extras .panel-shelf { margin-bottom: 70px; }
.shelf-item { display: inline-flex; }
.shelf-item button:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.panel-shelf .shelf-x { border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; padding: 4px 8px; }
.panel-shelf .shelf-x:hover { color: var(--danger); }

/* The size menu. */
.size-menu {
    position: fixed;
    z-index: 1100;
    display: grid;
    gap: 1px;
    min-width: 210px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: calc(var(--radius) + 2px);
    box-shadow: 0 14px 34px color-mix(in srgb, var(--text) 22%, transparent);
}
.size-menu button {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    text-align: left;
    font-size: .88rem;
}
.size-menu button:hover, .size-menu button:focus-visible { background: var(--surface-2); outline: none; }
.size-menu button[aria-checked="true"] { color: var(--accent); font-weight: 600; }
.sm-shape {
    flex: none;
    width: calc(var(--sw) * 3px + 4px);
    height: calc(var(--sh) * 5px + 2px);
    margin-right: calc((12 - var(--sw)) * 3px);
    border: 1.5px solid currentColor;
    border-radius: 3px;
    background: color-mix(in srgb, currentColor 12%, transparent);
}
.sm-fit { border-style: dashed; background: none; }

/* ---------- Tasks: sections, steps, swipes, order ---------- */

/* The Tasks tab's bar: views on the left, search and Select on the right. */
.tasks-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; margin-bottom: 14px; }
.tasks-toolbar .filter-row { margin: 0; flex: 1 1 auto; }
.tasks-tools { display: flex; gap: 8px; align-items: center; flex: 0 1 320px; }
#task-search {
    flex: 1;
    min-width: 0;
    height: 34px;
    padding: 0 12px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: .88rem;
}
#task-search:focus { outline: none; border-color: var(--accent); }
@media (max-width: 560px) { .tasks-tools { flex: 1 1 100%; } }

/* Estimates and the steps count, among the other margin notes. */
.chip.est { font-style: normal; font-variant-numeric: tabular-nums; }
.chip.steps {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    white-space: nowrap;
    gap: 4px;
    border: 0;
    background: none;
    padding: 0;
    color: var(--text-dim);
    font: inherit;
    font-style: normal;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}
.chip.steps svg { width: 12px; height: 12px; }
.chip.steps:hover { color: var(--accent); }
.chip.steps.all { color: var(--good); }
.chip.steps[aria-expanded="true"] { color: var(--accent); }

.steps { margin: 8px 0 2px; padding-left: 2px; display: grid; gap: 2px; }
.step {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 3px 0;
    font-size: .9rem;
    line-height: 1.35;
    cursor: pointer;
}
.step input { margin: 2px 0 0; width: 15px; height: 15px; accent-color: var(--good); flex: none; }
.step.done span { color: var(--text-faint); text-decoration: line-through; }
.step-add input {
    width: 100%;
    margin-top: 2px;
    padding: 5px 0 4px 24px;
    border: 0;
    border-bottom: 1px dashed var(--rule);
    background: none;
    color: var(--text);
    font: inherit;
    font-size: .88rem;
}
.step-add input:focus { outline: none; border-bottom-color: var(--accent); }

/* In the details sheet. */
.td-steps { display: grid; gap: 4px; margin-bottom: 4px; }
.td-step { display: flex; align-items: center; gap: 8px; }
.td-step input[type="text"] { flex: 1; min-width: 0; }
.td-step input[type="checkbox"] { accent-color: var(--good); width: 16px; height: 16px; }

/* Finishing: the tick pops and the line goes through before the row leaves. */
.task.completing .check { animation: check-pop .32s cubic-bezier(.2, 1.6, .4, 1); }
.task.completing .task-title { transition: color .3s; }
.task.completing .task-body { animation: row-settle .52s ease-in forwards; }
@keyframes check-pop { 0% { scale: .7; } 100% { scale: 1; } }
.habit-tick.pop, .ring-btn.pop { animation: check-pop .32s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes row-settle { 0%, 55% { opacity: 1; } 100% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
    .task.completing .check, .task.completing .task-body, .habit-tick.pop, .ring-btn.pop, .shared-tick.pop { animation: none; }
}

/* Your own order: the Reorder button at the bottom right of a list, and the
   list while it is on, where any row drags and shows a handle on its right. */
.reorder-bar { display: flex; justify-content: flex-end; margin-top: 6px; }
.reorder-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: none;
    color: var(--text-dim);
    font-size: .78rem;
    font-weight: 500;
}
.reorder-btn svg { width: 13px; height: 13px; }
.reorder-btn:hover { border-color: var(--accent); color: var(--accent); }
.reorder-btn[aria-pressed="true"] { background: var(--fill, var(--accent)); border-color: var(--fill, var(--accent)); color: var(--on-fill, var(--surface)); }
.reordering > [data-orderable] {
    position: relative;
    padding-right: 44px;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
}
/* The handle: a finger drags by it (it alone takes the touch), and anywhere
   else on the row scrolls the list as usual. */
.grip { display: none; }
.reordering > [data-orderable] > .grip {
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 44px;
    touch-action: none;
    cursor: grab;
}
.reordering > [data-orderable] > .grip::after {
    content: '';
    position: absolute;
    right: 12px;
    top: 50%;
    width: 14px;
    height: 18px;
    translate: 0 -50%;
    background: radial-gradient(circle, var(--text-faint) 1.5px, transparent 2px) 0 0 / 7px 6px;
}
.reordering .task-actions, .reordering .grid28, .reordering .habit [data-act="archive"] { display: none; }
/* Every row's buttons rest while the list is put in order, timed tasks' too. */
.reordering [data-id] button, .reordering [data-id] input { pointer-events: none; }
/* In a short widget the list scrolls in its box, with Done kept in reach. */
.board > .panel.short:has(.reordering) > .panel-body { overflow-y: auto; }
.board > .panel.short .reordering + .reorder-bar { position: sticky; bottom: 0; z-index: 6; padding: 4px 0 2px; background: var(--surface); }
.lifting {
    position: relative;
    z-index: 5;
    background: var(--surface);
    box-shadow: 0 8px 22px color-mix(in srgb, var(--text) 18%, transparent);
    border-radius: var(--radius-sm);
    cursor: grabbing;
}

/* Swiping, on a touch screen: the row slides over what the swipe will do. */
.task { touch-action: pan-y; }
.task.swiping { position: relative; overflow: hidden; }
.task.swiping > :not(.swipe-under) { translate: var(--dx, 0) 0; transition: translate .18s ease-out; }
.task.swiping:not(.swipe-gone) > :not(.swipe-under) { transition: none; }
.swipe-under {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 16px;
    font-size: .85rem;
    font-weight: 600;
    color: var(--surface);
    background: var(--text-faint);
    transition: background .15s;
}
.swipe-under span { display: inline-flex; align-items: center; gap: 6px; }
.swipe-under svg { width: 14px; height: 14px; }
.task[data-swipe="done"] .su-later, .task[data-swipe="later"] .su-done { visibility: hidden; }
.task.swipe-armed[data-swipe="done"] .swipe-under { background: var(--good); }
.task.swipe-armed[data-swipe="later"] .swipe-under { background: var(--fill, var(--accent)); }
.task.swipe-gone { transition: height .18s ease-in, padding .18s ease-in, opacity .18s; height: 0 !important; padding-top: 0; padding-bottom: 0; opacity: 0; }
/* Delete is on every row, phones included (it always asks first). Where a
   row has no room for buttons (small board widgets), tapping the title
   shows it beside the pencil; on a computer the row's own is enough. */
@media (hover: hover) { .title-delete { display: none; } }
.title-delete { color: var(--danger); }
.ci-delete { display: inline-flex; align-items: center; gap: 6px; }
.ci-delete svg { width: 15px; height: 15px; }

/* Choosing several. */
.tasks-view.selecting .task { cursor: pointer; }
.tasks-view.selecting .task-actions, .tasks-view.selecting .chip.steps { pointer-events: none; }
.tasks-view.selecting .task-actions { display: none; }
.tasks-view.selecting .check { border-style: dashed; }
.tasks-view.selecting .check svg { opacity: 0; }
.tasks-view.selecting .task.selected { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.tasks-view.selecting .task.selected .check { background: var(--fill, var(--accent)); border: 1.5px solid var(--fill, var(--accent)); }
.tasks-view.selecting .task.selected .check svg { opacity: 1; stroke: var(--surface); }
body.selecting-tasks .capture { visibility: hidden; }
.bulk-bar {
    position: fixed;
    left: 50%;
    translate: -50% 0;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px 12px;
    width: max-content;
    max-width: calc(100vw - 24px);
    padding: 9px 16px;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 20px;
    box-shadow: 0 10px 30px color-mix(in srgb, var(--text) 20%, transparent);
    font-size: .88rem;
}
/* On phones, both sit above the bottom navigation (this comes after their own bottom). */
@media (max-width: 760px) { .edit-bar, .bulk-bar { bottom: calc(var(--nav-h) + 14px); } }
.bulk-count { font-weight: 600; }
.bulk-acts { display: contents; }
.bulk-acts[hidden] { display: none; }
.bulk-bar button:not(.link-btn), .bulk-pick, .bulk-bar select {
    border: 1px solid var(--rule);
    background: var(--bg);
    color: var(--text);
    border-radius: 999px;
    padding: 4px 12px;
    font: inherit;
    font-size: .85rem;
}
.bulk-bar button:not(.link-btn):hover { border-color: var(--accent); color: var(--accent); }
.bulk-pick { position: relative; cursor: pointer; }
.bulk-pick input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }

/* "Done today", folded under today's list. */
.done-fold { margin-top: 8px; }
.done-fold summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    list-style: none;
    cursor: pointer;
    font-size: .82rem;
    color: var(--text-faint);
}
.done-fold summary::-webkit-details-marker { display: none; }
.done-fold summary svg { width: 12px; height: 12px; color: var(--good); }
.done-fold summary:hover { color: var(--text); }
.done-fold .card { background: none; border: 0; padding: 0; }

/* What the capture box has understood. */
.capture-preview {
    max-width: 1680px;
    margin: -2px auto 8px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 22px;
    align-items: center;
    font-size: .78rem;
}
.cp-chip { padding: 2px 9px; border-radius: 999px; background: var(--surface-2); color: var(--text-dim); }
.cp-chip.on { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--accent); }
.cp-chip.due { background: color-mix(in srgb, var(--danger) 12%, var(--surface)); color: var(--danger); }
.cp-chip.soft { background: none; color: var(--text-faint); padding-left: 0; }
.cp-tip { color: var(--text-faint); font-family: var(--serif); font-style: italic; }
.cp-tip b { font-family: var(--sans); font-style: normal; font-weight: 600; color: var(--text-dim); }

/* The shortcut list. */
.shortcuts { display: grid; grid-template-columns: max-content 1fr; gap: 8px 18px; margin: 6px 0 4px; align-items: center; }
.shortcuts dt { white-space: nowrap; color: var(--text-faint); font-size: .85rem; }
.shortcuts dd { margin: 0; }
kbd {
    display: inline-block;
    min-width: 22px;
    padding: 1px 6px;
    border: 1px solid var(--rule);
    border-bottom-width: 2px;
    border-radius: 5px;
    background: var(--surface);
    color: var(--text);
    font: 600 .8rem/1.4 var(--sans);
    text-align: center;
}

/* ---------- Tasks: three columns ---------- */

/* Today, the rest of this week, and what was missed, side by side; stacked
   on a phone, in that order. */
.task-columns {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
    align-items: start;
    margin-bottom: 26px;
}
/* A single long list (Inbox, Let go, Repeating) takes two of the three. */
.tcol.wide { grid-column: span 2; }
@media (max-width: 899px) {
    .task-columns { grid-template-columns: 1fr; }
    .tcol.wide { grid-column: auto; }
}
.tcol-hint { font-family: var(--serif); font-style: italic; font-size: .78rem; color: var(--text-faint); white-space: nowrap; }
@media (max-width: 480px) { .tcol-hint { display: none; } }
.tcol .empty { font-size: .86rem; }
.tcol #rule-form { padding-top: 6px; }
.tcol .card { background: none; border: 0; padding: 0; }
.tcol .upcoming-day:first-of-type { margin-top: 6px; }
.tcol-act { font-size: .8rem; }
.tcol-older { margin-top: 10px; border-top: 1px solid var(--rule-soft); padding-top: 6px; }
.tcol-older summary {
    cursor: pointer;
    list-style: none;
    padding: 4px 0;
    font-family: var(--serif);
    font-style: italic;
    font-size: .84rem;
    color: var(--text-faint);
}
.tcol-older summary::-webkit-details-marker { display: none; }
.tcol-older summary::before { content: "▸ "; font-style: normal; }
.tcol-older[open] summary::before { content: "▾ "; }
.tcol-older summary:hover { color: var(--text); }
/* A column holding two boxes: Let go, and Missed under it. */
.tcol-stack { display: grid; gap: 18px; align-content: start; min-width: 0; }
.tcol-more { margin-top: 8px; font-size: .82rem; }
.tcol .letgo-row .btn.small { flex: none; }

/* A task's title, being edited where it sits. */
.title-edit { display: flex; align-items: flex-start; gap: 2px; }
/* Its row buttons step aside: they would cover the pencil, and the box wants the width. */
.task:has(.title-edit) .task-actions { display: none; }
.title-edit textarea {
    flex: 1;
    min-width: 0;
    border: 0;
    border-bottom: 1px solid var(--accent);
    border-radius: 0;
    background: none;
    padding: 0 0 1px;
    line-height: 1.45;
    resize: none;
    overflow: hidden;
    outline: none;
}
.title-edit .icon-btn { margin-top: -4px; color: var(--text-dim); }
.tasks-compact .title-edit textarea { font-size: .92rem; }

/* A habit's days, on one line even on a phone. */
.habit-details .filter-row, .rule-details .filter-row { gap: 8px; }

/* ---------- Iconic themes: one signature touch each ----------
   Small details that make each look unmistakable. They key off the theme's
   id on <html>, so a person's own copy of a theme (made in Custom) does not
   carry them. Decoration only: nothing here carries meaning. Written as
   :root[data-theme] to sit level with the panel-style rules above. */

/* Fizz: buttons and bars filled with the red of its lines, with cream
   lettering; words in the accent stay white so they read on the red. */
:root[data-theme="fizz"] { --fill: #d12831; --on-fill: #fff7f2; }
/* Its cards are its own card colour, not the soft style's tint of the page. */
:root[data-theme="fizz"] .panel, :root[data-theme="fizz"] .panel[data-accent] { background: var(--surface); --under: var(--surface); }
:root[data-theme="fizz"] .day { background: var(--surface); --under: var(--surface); }
:root[data-theme="fizz"] .day.today { box-shadow: inset 0 0 0 1.5px rgba(255, 247, 242, .45); }
/* Fizz: bubbles rising faintly behind everything. */
:root[data-theme="fizz"] body {
    background-image:
        radial-gradient(circle, rgba(255, 255, 255, .09) 1.5px, transparent 2.5px),
        radial-gradient(circle, rgba(255, 255, 255, .06) 3px, transparent 4px);
    background-size: 38px 38px, 61px 61px;
    background-position: 0 0, 19px 27px;
    background-attachment: fixed;
}

/* Ketchup & Mustard: a stripe of mustard across the top of every card. */
:root[data-theme="ketchup-mustard"] .panel { border-top: 4px solid #ffc72c; }

/* Malibu: a pink-to-sky glow across the whole page, top bar and bottom
   bars included, so it reads as one sweep of colour. */
:root[data-theme="malibu"] {
    --malibu-glow: linear-gradient(100deg, color-mix(in srgb, #ff8fc7 45%, var(--bg)), color-mix(in srgb, #8fd3f5 45%, var(--bg)));
}
:root[data-theme="malibu"] body { background-image: var(--malibu-glow); background-attachment: fixed; }
:root[data-theme="malibu"] :is(.topbar, .capture, .bottom-nav) { background: var(--malibu-glow); }

/* Director's Cut: a cinema vignette, and the day set like a title card. */
:root[data-theme="directors-cut"] body {
    background-image: radial-gradient(ellipse at 50% 40%, transparent 55%, rgba(0, 0, 0, .38));
    background-attachment: fixed;
}
:root[data-theme="directors-cut"] .greeting { text-transform: uppercase; letter-spacing: .16em; font-size: 1.3rem; }
:root[data-theme="directors-cut"] .panel-title { font-style: italic; }

/* Mainframe: a soft screen glow and faint scanlines. */
:root[data-theme="mainframe"] body { text-shadow: 0 0 5px rgba(0, 255, 65, .25); }
:root[data-theme="mainframe"] body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
    background: repeating-linear-gradient(to bottom, transparent 0 2px, rgba(0, 0, 0, .16) 2px 3px);
}

/* Caution Tape: hazard stripes under the top bar and down the Missed card. */
:root[data-theme="caution-tape"] .topbar::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    height: 6px;
    background: repeating-linear-gradient(-45deg, #fff200 0 10px, #000 10px 20px);
}
:root[data-theme="caution-tape"] .panel.accent {
    border-left: 8px solid transparent;
    border-image: repeating-linear-gradient(-45deg, #fff200 0 8px, #000 8px 16px) 0 0 0 8;
}

/* Boardroom: a corporate blue bar along the top, and crisp small labels. */
:root[data-theme="boardroom"] .topbar { box-shadow: inset 0 4px 0 #0062ff; }
:root[data-theme="boardroom"] .panel-title { text-transform: uppercase; letter-spacing: .09em; font-size: .78rem; font-weight: 600; }

/* De Stijl: heavy black lines, and a block of primary colour by each title. */
:root[data-theme="de-stijl"] .panel { border: 3px solid #111111; }
:root[data-theme="de-stijl"] .greeting { font-weight: 700; }
:root[data-theme="de-stijl"] .panel-title::before {
    content: '';
    display: inline-block;
    width: .72em;
    height: .72em;
    margin-right: .5em;
    background: #e63946;
}
:root[data-theme="de-stijl"] .board > :nth-child(3n+2) .panel-title::before { background: #1d3557; }
:root[data-theme="de-stijl"] .board > :nth-child(3n+3) .panel-title::before { background: #f2c12e; }

/* Black Tie: hairline gold edges, small-capital titles, an italic day. */
:root[data-theme="black-tie"] .panel { border-color: rgba(227, 191, 110, .38); }
:root[data-theme="black-tie"] .panel-title { font-variant: small-caps; letter-spacing: .06em; }
:root[data-theme="black-tie"] .greeting { font-style: italic; }

/* Black Tie: gold leaf and lipstick red. The gold is a foil (light caught
   in highlights, with a few bright flecks) on the edges and the gold words;
   urgent is a lipstick-red tag with cream lettering, since a red that deep
   cannot be read as text on black. */
:root[data-theme="black-tie"] {
    --lipstick: #d1001f;
    --foil: linear-gradient(105deg, #c99a45 0%, #f3dc8e 18%, #d0a24c 34%, #fff3c4 48%, #cf9f48 62%, #ecd083 80%, #c4923c 100%);
    --foil-edge: linear-gradient(115deg, rgba(201, 154, 69, .35), rgba(255, 236, 170, .85) 22%, rgba(201, 154, 69, .3) 45%, rgba(243, 220, 142, .7) 70%, rgba(196, 146, 60, .35));
    --flecks: radial-gradient(circle at 30% 40%, #fffef5 0 .6px, transparent 1.2px) 0 0 / 23px 17px,
              radial-gradient(circle at 70% 20%, rgba(255, 250, 222, .85) 0 .5px, transparent 1px) 3px 5px / 29px 13px,
              radial-gradient(circle at 15% 75%, rgba(255, 255, 240, .9) 0 .7px, transparent 1.3px) 7px 2px / 37px 19px,
              radial-gradient(circle at 60% 60%, rgba(150, 108, 34, .45) 0 .5px, transparent 1px) 11px 9px / 31px 11px,
              radial-gradient(circle at 85% 85%, rgba(255, 248, 215, .75) 0 .4px, transparent .9px) 5px 7px / 17px 23px;
}
:root[data-theme="black-tie"] .panel { border-image: var(--foil-edge) 1; }
:root[data-theme="black-tie"] .notice:not(.error) { border-left: 3px solid; border-image: var(--foil) 1; }
:root[data-theme="black-tie"] :is(.flame, .section-title.warn, .panel.accent .panel-title,
    .nudge-warn .nudge-text b, .day-meter-line .warn, .dl-badge.soon, .plan-focus) {
    background: var(--foil) 0 0 / 90px 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
:root[data-theme="black-tie"] :is(.momentum span.today, .wp-bars span.today, .wp-badge.soon, .nudge-warn .nudge-dot) {
    background: var(--flecks), var(--foil);
}
:root[data-theme="black-tie"] :is(.prio-2, .chip.late) {
    background: var(--flecks), var(--foil) 0 0 / 70px 100%;
    color: #1a1a1a;
    padding: 1px 6px;
    border-radius: 2px;
    font-weight: 600;
    letter-spacing: .02em;
}
:root[data-theme="black-tie"] .prio-3 {
    background: var(--lipstick);
    color: #fff6f2;
    padding: 1px 6px;
    border-radius: 2px;
    letter-spacing: .02em;
}
:root[data-theme="black-tie"] :is(.dl-badge.now, .cp-chip.due) { background: var(--lipstick); color: #fff6f2; }
:root[data-theme="black-tie"] :is(.mo-dots em.due, .wp-badge.now, .btn.danger-btn) { background: var(--lipstick); border-color: var(--lipstick); color: #fff6f2; }


/* Legal Pad: every card a ruled sheet with a red double margin, and the
   headings handwritten in ballpoint. */
:root[data-theme="legal-pad"] .panel,
:root[data-theme="legal-pad"] .day {
    background-image:
        linear-gradient(90deg, transparent 5px, rgba(200, 16, 46, .5) 5px 6px, transparent 6px 8px, rgba(200, 16, 46, .5) 8px 9px, transparent 9px),
        repeating-linear-gradient(180deg, transparent 0 27px, rgba(60, 100, 190, .2) 27px 28px);
}
:root[data-theme="legal-pad"] .day { background-color: var(--surface); }
:root[data-theme="legal-pad"] :is(.greeting, .panel-title, .day-name) { font-family: var(--display); color: var(--accent); font-weight: 700; }
:root[data-theme="legal-pad"] .greeting { font-size: 2.6rem; line-height: 1; }
:root[data-theme="legal-pad"] .panel-title { font-size: 1.45rem; line-height: 1.1; }
:root[data-theme="legal-pad"] .day-name { font-size: 1.35rem; }

/* Chalkboard: chalk dust and old eraser smears on slate, headings in chalk,
   and a wooden chalk ledge along the bottom. */
:root[data-theme="chalkboard"] body {
    background-image:
        radial-gradient(ellipse 60% 25% at 30% 20%, rgba(241, 241, 230, .035), transparent 70%),
        radial-gradient(ellipse 50% 20% at 75% 65%, rgba(241, 241, 230, .03), transparent 70%),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 .09 0 0 0 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-attachment: fixed;
}
:root[data-theme="chalkboard"] :is(.greeting, .panel-title, .day-name) {
    font-family: var(--display);
    font-weight: 700;
    letter-spacing: .02em;
    text-shadow: 0 0 2px rgba(241, 241, 230, .45);
}
:root[data-theme="chalkboard"] .greeting { font-size: 2.3rem; }
:root[data-theme="chalkboard"] .panel-title { font-size: 1.2rem; }
:root[data-theme="chalkboard"] .panel { border-color: rgba(241, 241, 230, .2); }
:root[data-theme="chalkboard"] .capture { border-top: 7px solid #7b5533; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08); }


/* Seventies: groovy lettering and a band of brown, orange, mustard and
   avocado under the top bar. */
:root[data-theme="seventies"] .topbar { margin-bottom: 20px; }
:root[data-theme="seventies"] .topbar::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -12px;
    height: 12px;
    pointer-events: none;
    background: linear-gradient(180deg, #5a3418 0 25%, #c4561c 25% 50%, #e39a1e 50% 75%, #8a9a3a 75%);
}
:root[data-theme="seventies"] :is(.greeting, .panel-title, .day-name) { font-family: var(--display); font-weight: 400; font-style: normal; letter-spacing: .01em; }
:root[data-theme="seventies"] .greeting { font-size: 2.1rem; color: #5a3418; }
:root[data-theme="seventies"] .panel-title { color: var(--accent); }

/* ---------- Shared habits ---------- */
/* First on the Habits tab, each on a surface of its own with a stripe in the
   theme's colour (--c, the same as its buttons), so the people part stands
   apart from your own list. */
.shared-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
.shared-habit {
    --c: var(--fill, var(--accent));
    --on-c: var(--on-fill, var(--surface));
    background: var(--surface);
    border: 1px solid var(--rule);
    border-left: 4px solid var(--c);
    border-radius: var(--radius);
    padding: 9px 12px 9px 14px;
}
/* One row: the name and where things stand (a tap opens the week), then the circles. */
.shared-main { display: flex; align-items: center; gap: 10px; }
.shared-text {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; gap: 2px;
    padding: 2px 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
/* One line each while closed, so a list of them stays short; in full once opened. */
.shared-name { display: flex; align-items: center; min-width: 0; font-weight: 500; }
.shared-name span, .shared-status { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shared-habit.open :is(.shared-name span, .shared-status) { white-space: normal; overflow-wrap: anywhere; }
.shared-name::after {
    content: ''; flex: 0 0 auto; width: 6px; height: 6px; margin: 0 2px 2px 8px;
    border-right: 1.5px solid var(--text-faint); border-bottom: 1.5px solid var(--text-faint);
    transform: rotate(-45deg); transition: transform .15s;
}
.shared-habit.open .shared-name::after { transform: rotate(45deg); }
.shared-status { font-size: .82rem; color: var(--text-dim); }

/* Everyone else as a small overlapping stack of circles with their initials,
   filled in once they have done it today. On the board, smaller still. */
.faces-stack { flex: 0 0 auto; display: inline-flex; }
.faces-stack i {
    width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    font-style: normal; font-size: .72rem; font-weight: 600;
    background: var(--surface-2); color: var(--text-dim);
    box-shadow: 0 0 0 2px var(--surface);
}
.faces-stack i + i { margin-left: -6px; }
.faces-stack i.on { background: var(--c); color: var(--on-c); }
.faces-stack i.rest { font-size: .66rem; font-weight: 500; }
.faces-stack.mini { vertical-align: -3px; margin-right: 7px; }
.faces-stack.mini i { width: 17px; height: 17px; font-size: .6rem; }
.faces-stack.mini i + i { margin-left: -4px; }

/* Your tick: a circle in the theme's colour, dashed until you have done it today. */
.shared-tick {
    flex: 0 0 auto;
    width: 34px; height: 34px; border-radius: 50%;
    display: grid; place-items: center; padding: 0;
    border: 2px dashed var(--c); background: none; cursor: pointer;
    transition: background .15s, transform .12s;
}
.shared-tick svg { width: 16px; height: 16px; stroke: var(--c); opacity: .35; }
.shared-tick.on { border-style: solid; background: var(--c); }
.shared-tick.on svg { stroke: var(--on-c); opacity: 1; }
.shared-tick:active { transform: scale(.92); }
.shared-tick:focus-visible { outline: 2px solid var(--c); outline-offset: 3px; }
.shared-tick.pop { animation: check-pop .32s cubic-bezier(.2, 1.6, .4, 1); }

/* The last seven days, in the squares your own habits use. */
.shared-members { list-style: none; margin: 9px 0 0; padding: 8px 0 0; border-top: 1px solid var(--rule-soft); }
.shared-members li { display: grid; grid-template-columns: minmax(0, 1fr) auto 58px; align-items: center; gap: 10px; padding: 3px 0; font-size: .86rem; }
.shared-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-dim); }
.week7 { display: inline-flex; gap: 4px; }
.week7 i { width: 11px; height: 11px; border-radius: 2px; background: var(--surface-2); }
.week7 i.on { background: var(--c); }
.week7 i.today:not(.on) { box-shadow: inset 0 0 0 1.5px var(--rule); }
.shared-run { font-size: .78rem; color: var(--text-dim); text-align: right; }
.shared-foot { display: flex; justify-content: flex-end; gap: 16px; margin-top: 8px; }
.shared-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }

/* No shared habits yet: one quiet invitation, not an empty section. */
.shared-invite {
    background: var(--surface);
    border: 1px dashed var(--rule);
    border-radius: var(--radius);
    padding: 14px 16px;
}
.shared-invite p { margin: 0; color: var(--text-dim); font-size: .92rem; }

/* In the Habits widget: the same rows as the habits above them, carrying on the list. */
.shared-rows { border-top: 1px solid var(--rule-soft); }
.shared-rows:first-child { border-top: 0; }
.shared-row { --c: var(--fill, var(--accent)); --on-c: var(--on-fill, var(--surface)); display: flex; align-items: center; gap: 13px; padding: 11px 2px; }
.shared-row + .shared-row { border-top: 1px solid var(--rule-soft); }
.shared-row .habit-tick[aria-pressed="true"] { background: var(--c); border-color: var(--c); }
.shared-row .habit-tick svg { stroke: var(--on-c); }
.shared-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1rem; letter-spacing: .04em; text-align: center;
    padding: 10px 12px; margin: 6px 0 4px; background: var(--surface-2); border-radius: 8px; user-select: all; overflow-wrap: anywhere; }
.swatches { display: flex; gap: 10px; }
.swatches button { width: 30px; height: 30px; border-radius: 50%; border: 3px solid transparent; outline-offset: 2px; cursor: pointer; }
.swatches button[aria-pressed="true"] { border-color: var(--surface); box-shadow: 0 0 0 2px var(--text); }
.form-error { color: var(--danger); font-size: .88rem; margin: 6px 0 0; }

/* ---------- AI planning ---------- */
.capture-ai { padding: 0 12px; }
.capture-ai svg { width: 18px; height: 18px; display: block; }
.ai-link { display: inline-flex; align-items: center; gap: 6px; }
.ai-link svg { width: 15px; height: 15px; }
.ai-thinking { color: var(--text-dim); margin: 18px 0 10px; }
.ai-thinking::after { content: ""; display: inline-block; width: 1.2em; text-align: left; animation: ai-dots 1.2s steps(4) infinite; }
@keyframes ai-dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }
@media (prefers-reduced-motion: reduce) { .ai-thinking::after { animation: none; content: "\2026"; } }
.ai-note { font-family: var(--serif); font-style: italic; margin: 6px 0 12px; }
.ai-list { margin: 0; padding: 0; list-style: none; }
.ai-list li { border-top: 1px solid var(--rule-soft); }
.ai-list label { display: flex; gap: 12px; align-items: flex-start; padding: 10px 0; cursor: pointer; }
.ai-list input { margin-top: 3px; flex: none; width: 18px; height: 18px; accent-color: var(--accent); }
.ai-list b { font-weight: 500; overflow-wrap: anywhere; }
.ai-chip { display: inline-block; font-size: .72rem; color: var(--text-dim); background: var(--surface-2); border-radius: 999px; padding: 1px 8px; margin-left: 6px; vertical-align: 1px; }
.ai-why, .ai-steps { display: block; font-size: .82rem; color: var(--text-faint); margin-top: 2px; }
.ai-sheet textarea { width: 100%; resize: vertical; font: inherit; }

/* ---------- In the phone apps: an app, not a web page ---------- */
/* No selecting the words on buttons and rows, no long-press callout, no grey
   flash on a tap, no double-tap zoom, and no rubber band that shows the page
   coming loose. Fields, and anything marked .selectable, still select. */
html.native {
    -webkit-user-select: none; user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}
html.native, html.native body { overscroll-behavior: none; }
html.native :is(input, textarea, [contenteditable="true"], .selectable) {
    -webkit-user-select: text; user-select: text; -webkit-touch-callout: default;
}

/* ---------- Sheets on a phone ---------- */
/* Up from the bottom edge with a handle, as in iPhone apps; pulled down by
   the handle (or from the top of the sheet) to close (sheetPull in app.js). */
@media (max-width: 600px) {
    .sheet-backdrop {
        padding: max(28px, env(safe-area-inset-top, 0px)) 0 0;
        animation: sheet-dim .22s ease-out;
    }
    .sheet-backdrop > .sheet {
        position: relative;
        max-width: none;
        max-height: calc(100dvh - max(28px, env(safe-area-inset-top, 0px)));
        margin: 0;
        border-width: 1px 0 0;
        border-radius: 16px 16px 0 0;
        padding: 26px 18px calc(18px + env(safe-area-inset-bottom, 0px));
        overscroll-behavior: contain;
        animation: sheet-up .3s cubic-bezier(.2, .9, .3, 1);
    }
    .sheet-backdrop > .sheet::before {
        content: ''; position: absolute; top: 8px; left: 50%;
        width: 38px; height: 5px; margin-left: -19px; border-radius: 3px;
        background: var(--rule);
    }
}
@keyframes sheet-up { from { transform: translateY(100%); } }
@keyframes sheet-dim { from { background: transparent; } }

/* ---------- Pull down to sync (the apps, and Jots on a home screen) ---------- */
.pull-sync {
    position: fixed; z-index: 65; left: 50%;
    top: calc(env(safe-area-inset-top, 0px) - 30px);
    width: 36px; height: 36px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--surface); color: var(--text-dim);
    box-shadow: 0 2px 10px color-mix(in srgb, var(--text) 18%, transparent);
    opacity: 0; transform: translate(-50%, 0);
    transition: transform .25s ease-out, opacity .25s ease-out;
    pointer-events: none;
}
.pull-sync svg { width: 18px; height: 18px; }
.pull-sync.ready { color: var(--accent); }
.pull-sync.spinning { opacity: 1; color: var(--accent); }
.pull-sync.spinning svg { animation: pull-spin .8s linear infinite; }
@keyframes pull-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .sheet-backdrop, .sheet-backdrop > .sheet { animation: none; }
    .pull-sync.spinning svg { animation-duration: 2.4s; }
}

/* ---------- The logo ---------- */
/* On a computer the logo starts the tab line, like a site's masthead; a phone
   has no top tabs, so there the monogram stands beside the day instead. */
.topbar-nav {
    display: flex;
    align-items: flex-end;
    gap: 36px;
    /* The line under the tabs, drawn inside so the open tab's underline lies on it. */
    box-shadow: inset 0 -1px 0 var(--rule);
}
.topbar-nav .tabs { flex: 1; min-width: 0; margin-top: 0; border-bottom: 0; }
.topbar-nav .tabs button { margin-bottom: 0; }
.brand { display: flex; flex: none; align-items: center; padding-bottom: 9px; }
.brand .logo-mark { height: 30px; }
.logo-word {
    font-family: var(--serif);
    font-style: italic;
    font-size: 1.75rem;
    line-height: 30px;
    color: var(--accent);
    /* The gap to the logo, plus however far this font's italic j sweeps left
       of its box (--logo-lean, set per font in app.js), so the j's tail keeps
       the same clear space from the logo in every font and at any size. */
    margin-left: calc(.2em + var(--logo-lean, .2em));
    /* Optical: the italic leans past its box on the right too. */
    padding-right: 2px;
    transform: translateY(-1px);
}
.topbar .topbar-row { margin-top: 18px; }
.day-title { display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand-mark { display: none; flex: none; }
.brand-mark .logo-mark { height: 40px; }
@media (max-width: 760px) {
    .topbar-nav { display: none; }
    .topbar .topbar-row { margin-top: 0; align-items: center; }
    .brand-mark { display: flex; }
}
@media (max-width: 430px) {
    .brand-mark .logo-mark { height: 34px; }
}

/* The monogram is drawn in the theme's own colours: the J in its accent, the
   bar, S and O in its warm colour softened toward the page. The strokes blend
   where they cross (darker on light pages, lighter on dark ones), as inks
   would. On Sand & clay this is the logo exactly as drawn. */
.logo-mark {
    display: block;
    width: auto;
    overflow: visible;
    isolation: isolate;
    fill: none;
    stroke-linecap: round;
    stroke-width: 24.5;
    /* How strong the bar, O and S are against the page: as mix percentages,
       and as plain opacities for browsers without color-mix. */
    --mk-bar: 55%; --mk-o: 75%; --mk-s: 35%;
    --mk-bar-a: .55; --mk-o-a: .75; --mk-s-a: .35;
    --mk-blend: multiply;
}
:root[data-tone="dark"] .logo-mark {
    --mk-bar: 80%; --mk-o: 88%; --mk-s: 55%;
    --mk-bar-a: .8; --mk-o-a: .88; --mk-s-a: .55;
    --mk-blend: screen;
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) .logo-mark {
        --mk-bar: 80%; --mk-o: 88%; --mk-s: 55%;
        --mk-bar-a: .8; --mk-o-a: .88; --mk-s-a: .55;
        --mk-blend: screen;
    }
}
.logo-mark > * { mix-blend-mode: var(--mk-blend); }
.mark-j   { stroke: var(--accent); }
/* Older browsers (before color-mix: Safari 16.1, Chrome 110, Firefox 112):
   the same colours, let through to the page by opacity. A color-mix inside
   a plain declaration would fail only once var() is filled in, leaving the
   stroke blank, so the mixed colours sit behind @supports instead. */
.mark-bar { stroke: var(--warn); stroke-opacity: var(--mk-bar-a); }
.mark-o   { stroke: var(--warn); stroke-opacity: var(--mk-o-a); }
.mark-s   { stroke: var(--warn); stroke-opacity: var(--mk-s-a); }
@supports (color: color-mix(in srgb, red 50%, blue)) {
    .mark-bar, .mark-o, .mark-s { stroke-opacity: 1; }
    .mark-bar { stroke: color-mix(in srgb, var(--warn) var(--mk-bar), var(--bg)); }
    .mark-o   { stroke: color-mix(in srgb, color-mix(in srgb, var(--warn) 50%, var(--accent)) var(--mk-o), var(--bg)); }
    .mark-s   { stroke: color-mix(in srgb, var(--warn) var(--mk-s), var(--bg)); }
}

/* ---------- Browsers from before color-mix (Safari 16.1, Chrome 110, Firefox 112) ----------
   A color-mix() that holds a var() is only found wanting once the var() is
   filled in, and the property then falls back to nothing: a see-through
   header, a heatmap with no squares. Here, plain colours and opacities stand
   in where that would be broken, not just a little plainer. */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
    .topbar, .capture, .bottom-nav { background: var(--bg); }
    :root[data-theme="malibu"] { --malibu-glow: var(--bg); }
    .sheet-backdrop { background: rgba(0, 0, 0, .4); }
    .cm-frame::after { background: var(--bg); opacity: .72; }

    .day-meter-bar i.open { background: var(--accent); opacity: .35; }
    .day-meter.over .day-meter-bar i.open { background: var(--warn); opacity: .55; }
    .heat i[data-level="1"] { background: var(--accent); opacity: .3; }
    .heat i[data-level="2"] { background: var(--accent); opacity: .55; }
    .heat i[data-level="3"] { background: var(--accent); opacity: .8; }
    .wp-month span.dot { background: var(--accent); opacity: .5; }

    :root[data-panels="soft"] .panel,
    :root[data-panels="soft"] .panel[data-accent] { background: var(--surface); --under: var(--surface); }
    .day.today, .layer-row.on, .cp-chip.on,
    .tasks-view.selecting .task.selected { background: var(--accent-soft); }
    .notice.error, .dl-badge.now, .cp-chip.due { background: var(--warn-soft); }
    .plan-habit { background: var(--surface-2); }
    .sm-shape { background: var(--surface-2); }

    /* Borders would otherwise take the text colour. */
    .closing, .week-grid .day.today { border-color: var(--accent); }
    .panel.accent { border-color: var(--warn); }
    .panel[data-accent], .theme-preview, .theme-preview.split .tp + .tp,
    .colour-map[data-spot] .cm-card.cm-on { border-color: var(--rule); }
    .panel[data-accent] .panel-head { border-bottom-color: var(--rule-soft); }
    .nudge-act { text-decoration-color: var(--rule); }
}
