/* The assistant panel.
 *
 * Inside App.Shawn this fills the stage to the right of the WPF sidebar, so the
 * palette is lifted from App.xaml and must stay in step with it. On a phone the
 * warm palette takes over further down.
 *
 * Two rules run through everything here. Text ARRIVES rather than appears: each
 * word fades in while it lifts three pixels and sheds a blur, and only words
 * that have arrived exist in the document, so the paragraph grows the way real
 * tokens do. And nothing changes without a transition — a panel opening, a task
 * ticking, a bar moving, a number counting.
 */

:root {
  --canvas:#F4F7FB; --sidebar:#FBFCFE; --surface:#FFFFFF;
  --border:#E3E9F1; --hairline:rgba(22,32,51,.07); --track:rgba(22,32,51,.055);
  --text:#162033; --muted:#667085; --dim:#8A94A6;
  --accent:#2867E8; --accent-hover:#1F58CD; --accent-soft:#EAF1FF; --accent-pale:#B9CCEF;
  --success:#168A5B; --danger:#C83D4D; --field:#F7F9FC;
  --mine:#E4EAF3; --mine-text:#1C2940;
  --warm:oklch(0.60 0.135 58); --warm-soft:oklch(0.965 0.024 72);
  --ui:"Segoe UI Variable Text","Segoe UI Variable","Segoe UI",system-ui,-apple-system,sans-serif;
  --serif:"Newsreader",Georgia,"Times New Roman",serif;
  --ease:cubic-bezier(0.32,0.72,0,1);
  --soft:cubic-bezier(0.2,0.6,0.2,1);
}

* { box-sizing:border-box; }
html, body { height:100%; }
body {
  margin:0; font-family:var(--ui); font-size:13.5px; color:var(--text);
  background:var(--canvas); -webkit-font-smoothing:antialiased;
  overflow:hidden;
}
button { font-family:inherit; border:0; background:none; cursor:pointer; color:inherit; }
a { color:var(--accent); text-decoration:none; }
a:hover { color:var(--accent-hover); }

.stage { display:flex; height:100%; min-height:0; position:relative; }

/* ── the token gate, which App.Shawn never sees ─────────────────────────────── */
.gate { position:absolute; inset:0; z-index:40; display:flex; align-items:center;
        justify-content:center; background:var(--canvas); }
.gate.hidden { display:none; }
.gatebox { width:360px; }
.gatebox h1 { font-family:var(--serif); font-size:24px; font-weight:500; margin:0 0 6px; }
.gatebox p { color:var(--muted); margin:0 0 18px; line-height:1.5; }
.gatebox input { width:100%; height:42px; border-radius:11px; border:1px solid var(--border);
                 background:var(--field); padding:0 13px; font-family:var(--ui); font-size:13.5px;
                 outline:none; transition:border-color .2s var(--soft); }
.gatebox input:focus { border-color:rgba(40,103,232,.45); background:#fff; }

/* ── conversation ───────────────────────────────────────────────────────────── */
.convo { flex:1; min-width:0; display:flex; flex-direction:column; position:relative; z-index:1; }

.chead { flex:none; height:64px; padding:0 20px 0 30px; display:flex; align-items:center;
         gap:10px; border-bottom:1px solid var(--hairline); min-width:0; }
.cheadwrap { min-width:0; overflow:hidden; }
.ctitle { font-family:var(--serif); font-size:19px; font-weight:500; letter-spacing:-.012em;
          white-space:nowrap; }
.csub { font-size:12.5px; color:var(--muted); margin-top:1px; white-space:nowrap; overflow:hidden;
        max-height:20px; opacity:1; transition:max-height .38s var(--ease), opacity .28s var(--ease); }
.csub.hid { max-height:0; opacity:0; }
.chiplive { margin-left:auto; flex:none; display:flex; align-items:center; gap:7px; height:30px;
            padding:0 12px 0 10px; border-radius:15px; background:var(--accent-soft);
            color:var(--accent); font-size:12px; font-weight:600; white-space:nowrap;
            font-variant-numeric:tabular-nums; cursor:pointer;
            opacity:0; transform:scale(.9); pointer-events:none;
            transition:opacity .35s var(--soft), transform .4s var(--ease); }
.chiplive.on { opacity:1; transform:none; pointer-events:auto; }
.ghost { height:30px; padding:0 12px; border-radius:9px; color:var(--muted); font-size:12px;
         font-weight:600; display:flex; align-items:center; flex:none;
         transition:background .18s var(--soft), color .18s var(--soft); }
.ghost:hover { background:var(--track); color:var(--text); }

.stream { flex:1; min-height:0; padding:24px 30px 6px; display:flex; flex-direction:column;
          gap:16px; overflow-y:auto; overflow-x:hidden; scroll-behavior:smooth; }
.stream::-webkit-scrollbar { width:9px; }
.stream::-webkit-scrollbar-thumb { background:rgba(22,32,51,.14); border-radius:5px;
                                   border:3px solid var(--canvas); }

.entry { display:flex; gap:15px; align-items:flex-start; animation:rise .44s var(--ease) both; }
@keyframes rise { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
.when { width:38px; flex:none; text-align:right; font-size:11px; font-weight:600; color:var(--muted);
        font-variant-numeric:tabular-nums; letter-spacing:.02em; padding-top:6px; }
.body { flex:1; min-width:0; }
.prose { font-family:var(--serif); font-size:16.5px; line-height:1.55; letter-spacing:-.003em;
         max-width:470px; text-wrap:pretty; }
/* His words, in a soft grey-blue bubble on the right: the look Shawn chose on 21 September ("Rose tint").
   Two of his in a row, to the same one, in the same minute, share the corner where they meet. */
.mine { width:fit-content; max-width:min(78%, 460px); margin-left:auto; padding:9px 14px; border-radius:16px;
        background:var(--mine); color:var(--mine-text); font-size:14px; line-height:1.45;
        white-space:pre-wrap; overflow-wrap:anywhere; }
.mine + .mine { margin-top:4px; border-top-right-radius:5px; }
.mine:has(+ .mine) { border-bottom-right-radius:5px; }
/* The time sits on the line of the first words beside it. */
.entry.fromhim .when { padding-top:12px; }
.entry.fromhim.labelled .when, .entry[data-who="companion"] .when { padding-top:0; }

/* a word that has arrived but not yet landed */
.w { display:inline-block; opacity:0; transform:translateY(3px); filter:blur(3px);
     margin-right:.26em;
     transition:opacity .38s var(--ease), transform .38s var(--ease), filter .38s var(--ease); }
.w.on { opacity:1; transform:none; filter:blur(0); }

.think { display:flex; gap:5px; align-items:center; height:26px; }
.think i { width:5px; height:5px; border-radius:50%; background:#B7C0CE; display:block;
           animation:pulse 1.25s var(--ease) infinite; }
.think i:nth-child(2) { animation-delay:.16s; }
.think i:nth-child(3) { animation-delay:.32s; }
@keyframes pulse { 0%,60%,100% { opacity:.35; transform:scale(.82); } 30% { opacity:1; transform:scale(1); } }

.chips { display:flex; flex-wrap:wrap; gap:8px; max-width:470px; margin-top:13px; }
.chip { height:34px; padding:0 15px; border-radius:10px; background:var(--surface);
        border:1px solid var(--border); display:flex; align-items:center; font-size:13px;
        font-weight:500; opacity:0; transform:translateY(7px);
        transition:opacity .4s var(--soft), transform .46s var(--ease),
                   border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease); }
.chip.on { opacity:1; transform:none; }
.chip:hover { border-color:rgba(40,103,232,.4); background:#F7FAFF; color:var(--accent); }
.chip:active { transform:scale(.975); }
.chips.gone .chip { opacity:0; transform:translateY(-5px); }

.composer { flex:none; padding:12px 30px 20px; }
.field { height:46px; border-radius:12px; background:var(--field); border:1px solid var(--border);
         display:flex; align-items:center; padding:0 7px 0 15px; gap:7px;
         transition:border-color .2s var(--ease), background .2s var(--ease); }
.field:focus-within { border-color:rgba(40,103,232,.45); background:#fff; }
.field input { flex:1; min-width:0; border:0; outline:0; background:transparent;
               font-family:var(--ui); font-size:13.5px; color:var(--text); }
.field input::placeholder { color:#A6AFBE; }
.round { width:32px; height:32px; border-radius:50%; display:flex; align-items:center;
         justify-content:center; flex:none;
         transition:transform .18s var(--ease), background .18s var(--ease), opacity .2s var(--soft); }
.round:active { transform:scale(.92); }
.round.mic { background:var(--track); color:var(--muted); }
.round.send { background:var(--accent); color:#fff; }
.round.send:hover { background:var(--accent-hover); }
.round[disabled] { opacity:.4; pointer-events:none; }

/* ── the rail ───────────────────────────────────────────────────────────────── */
.rail { flex:none; width:316px; border-left:1px solid var(--hairline); background:var(--sidebar);
        padding:24px 22px; display:flex; flex-direction:column; gap:14px;
        overflow-y:auto; overflow-x:hidden; position:relative; z-index:1;
        transition:width .52s var(--ease); }
.rail.open { width:620px; }
.panel { background:var(--surface); border:1px solid var(--hairline); border-radius:16px;
         padding:16px 18px 18px; cursor:pointer;
         transition:box-shadow .38s var(--ease), border-color .24s var(--ease); }
.panel:hover { border-color:#D3DCEA; }
.panel.big { box-shadow:0 12px 34px -16px rgba(22,32,51,.24); border-color:var(--hairline);
             cursor:default; }
.ptitle { font-size:10.5px; font-weight:700; color:var(--dim); letter-spacing:.08em;
          text-transform:uppercase; margin-bottom:12px; }
.swap { animation:rise .46s var(--ease) both; }
.bigt { font-size:30px; font-weight:600; letter-spacing:-.022em; font-variant-numeric:tabular-nums; }
.huget { font-family:var(--serif); font-size:52px; font-weight:500; letter-spacing:-.028em;
         font-variant-numeric:tabular-nums; line-height:1; }
.note { font-size:12.5px; color:var(--muted); line-height:1.45; }
.bar { height:5px; border-radius:2.5px; background:var(--track); overflow:hidden; }
.bar > i { display:block; height:100%; border-radius:2.5px; background:var(--accent);
           transition:width .62s var(--ease); }
.est { margin-left:auto; font-size:12.5px; color:var(--muted); font-variant-numeric:tabular-nums;
       flex:none; padding-left:10px; }

.ev { border-radius:10px; padding:8px 10px; margin:0 -10px;
      transition:background .2s var(--ease); }
.ev:hover { background:var(--track); }
.evtop { display:flex; gap:11px; align-items:flex-start; }
.evtime { width:40px; flex:none; font-size:12.5px; color:var(--muted);
          font-variant-numeric:tabular-nums; padding-top:1px; }
.rule { width:2px; border-radius:1px; flex:none; align-self:stretch; }
.evname { font-size:13.5px; font-weight:500; }
.evmeta { font-size:12px; color:var(--dim); margin-top:2px; }
.tag { display:inline-flex; align-items:center; height:17px; padding:0 6px; border-radius:5px;
       background:var(--track); color:var(--muted); font-size:10.5px; font-weight:600;
       letter-spacing:.03em; }
/* 0fr to 1fr animates height without measuring anything */
.detail { display:grid; grid-template-rows:0fr; opacity:0;
          transition:grid-template-rows .42s var(--ease), opacity .3s var(--ease); }
.detail.open { grid-template-rows:1fr; opacity:1; }
.detail > div { overflow:hidden; }
.detailin { padding:9px 0 2px 51px; font-size:12.5px; color:var(--muted); line-height:1.5; }

.task { display:flex; align-items:center; gap:10px; border-radius:9px; padding:7px 10px;
        margin:0 -10px; transition:background .2s var(--ease); }
.task:hover { background:var(--track); }
.mark { width:18px; height:18px; border-radius:50%; border:1.6px solid #C6CEDA; flex:none;
        display:flex; align-items:center; justify-content:center;
        transition:background .3s var(--ease), border-color .3s var(--ease); }
.mark.done { background:var(--success); border-color:var(--success); }
.mark svg { opacity:0; transform:scale(.4);
            transition:opacity .26s var(--ease), transform .34s cubic-bezier(.34,1.56,.64,1); }
.mark.done svg { opacity:1; transform:scale(1); }
.tlabel { font-size:13.5px; text-align:left; flex:1; min-width:0;
          background-image:linear-gradient(currentColor,currentColor);
          background-repeat:no-repeat; background-position:0 62%; background-size:0% 1.2px;
          transition:background-size .38s var(--ease), color .38s var(--ease); }
.tlabel.done { background-size:100% 1.2px; color:var(--muted); }
.btn { height:32px; padding:0 15px; border-radius:10px; display:flex; align-items:center;
       justify-content:center; font-size:13px; font-weight:600;
       transition:background .18s var(--ease), border-color .18s var(--ease), transform .18s var(--ease); }
.btn:active { transform:scale(.975); }
.btn.solid { background:var(--accent); color:#fff; }
.btn.solid:hover { background:var(--accent-hover); }
.btn.line { color:var(--muted); border:1px solid var(--border); background:var(--surface); }
.btn.line:hover { border-color:#C9D3E2; color:var(--text); }

/* ── the morning, and the night ─────────────────────────────────────────────── */
.wash { position:absolute; inset:0; pointer-events:none; opacity:0; z-index:0;
        transition:opacity 1.5s var(--soft); }
.wash.dawn { background:radial-gradient(120% 62% at 50% -8%, oklch(0.96 0.045 78) 0%, transparent 62%); }
.wash.dusk { background:radial-gradient(120% 58% at 50% 108%, oklch(0.93 0.035 262) 0%, transparent 60%); }
.wash.on { opacity:1; }
.wash.fade { opacity:0; }

.ceremony { flex:none; overflow:hidden; max-height:260px; opacity:1;
            transition:max-height .8s var(--ease), opacity .5s var(--soft); }
.ceremony.gone { max-height:0; opacity:0; }
.cerin { padding:34px 34px 0; }
.datewrap { text-align:center; margin-bottom:24px; }
.weekday { font-size:11px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
           color:var(--dim); opacity:0; transform:translateY(5px);
           transition:opacity .6s var(--soft) .12s, transform .6s var(--ease) .12s; }
.weekday.on { opacity:1; transform:none; }
.bigdate { font-family:var(--serif); font-size:34px; font-weight:500; letter-spacing:-.022em;
           margin-top:5px; opacity:0; transform:translateY(9px); filter:blur(7px);
           transition:opacity .8s var(--soft), transform .9s var(--ease), filter .8s var(--soft); }
.bigdate.on { opacity:1; transform:none; filter:blur(0); }

/* The day as proportional segments: each piece owns its share of the width, so
   nothing can overlap and no label can collide. The ruler underneath says when. */
.ribbon { margin:0 2px; opacity:0; transition:opacity .5s var(--soft); }
.ribbon.on { opacity:1; }
.segs { display:flex; gap:3px; height:30px; }
.seg { flex-grow:0; flex-basis:0; flex-shrink:1; min-width:0; overflow:hidden; border-radius:7px;
       display:flex; align-items:center; padding:0 9px;
       transition:flex-grow .68s var(--ease), opacity .45s var(--soft); }
.seg span { font-size:11px; font-weight:600; white-space:nowrap; overflow:hidden;
            text-overflow:ellipsis; font-variant-numeric:tabular-nums; }
.seg.free { background:var(--accent-soft); color:#5478B8; }
.seg.fixed { background:var(--accent); color:#fff; }
.seg.held { background:var(--warm-soft); color:oklch(0.42 0.10 58); box-shadow:inset 3px 0 0 var(--warm); }
.ruler { position:relative; height:19px; margin-top:5px; }
.tick { position:absolute; top:0; display:flex; flex-direction:column; }
.tick i { width:1px; height:4px; background:#CBD3E0; display:block; }
.tick span { font-size:10px; font-weight:600; color:#9AA4B4; margin-top:3px;
             font-variant-numeric:tabular-nums; white-space:nowrap; }
.tick.first { align-items:flex-start; }
.tick.mid { align-items:center; transform:translateX(-50%); }
.tick.last { align-items:flex-end; transform:translateX(-100%); }
.legend { display:flex; flex-wrap:wrap; gap:14px; margin-top:9px; min-height:16px; }
.lg { display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--muted);
      opacity:0; transform:translateY(4px);
      transition:opacity .45s var(--soft), transform .5s var(--ease); }
.lg.on { opacity:1; transform:none; }
.lgdot { width:9px; height:9px; border-radius:3px; flex:none; }

/* the closing record */
.sheet { position:absolute; inset:0; z-index:6; background:var(--canvas); padding:24px 34px;
         overflow-y:auto; opacity:0; pointer-events:none;
         transition:opacity .5s var(--soft); }
.sheet.on { opacity:1; pointer-events:auto; }
.stats { display:flex; gap:12px; margin-top:18px; }
.tile { flex:1; background:var(--surface); border:1px solid var(--hairline); border-radius:16px;
        padding:14px 18px; opacity:0; transform:translateY(10px);
        transition:opacity .55s var(--soft), transform .62s var(--ease); }
.tile.on { opacity:1; transform:none; }
.tile:nth-child(2) { transition-delay:.07s; }
.tile:nth-child(3) { transition-delay:.14s; }
.tlab { font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--dim); }
.tval { font-family:var(--serif); font-size:30px; font-weight:500; letter-spacing:-.024em;
        font-variant-numeric:tabular-nums; margin-top:4px; }
.tnote { font-size:12px; color:var(--muted); margin-top:2px; }
.chartcard { background:var(--surface); border:1px solid var(--hairline); border-radius:16px;
             padding:16px 20px 12px; margin-top:12px; opacity:0; transform:translateY(10px);
             transition:opacity .55s var(--soft), transform .62s var(--ease); }
.chartcard.on { opacity:1; transform:none; }
.plot { position:relative; height:118px; margin-top:14px; display:flex; align-items:flex-end;
        gap:14px; padding-bottom:20px; }
.col { flex:1; display:flex; flex-direction:column; justify-content:flex-end; align-items:center;
       height:100%; position:relative; }
.colbar { width:100%; max-width:62px; border-radius:4px 4px 0 0; background:var(--accent-pale);
          height:0; transition:height .62s var(--ease); }
.colbar.today { background:var(--accent); }
.xlab { position:absolute; bottom:-18px; font-size:11px; color:var(--dim);
        font-variant-numeric:tabular-nums; white-space:nowrap; }
.col.today .xlab { color:var(--text); font-weight:600; }
.banner { position:absolute; left:34px; right:34px; bottom:20px; z-index:8; display:flex;
          align-items:center; gap:12px; padding:13px 14px 13px 16px; border-radius:14px;
          background:var(--surface); border:1px solid var(--hairline);
          box-shadow:0 16px 38px -22px rgba(22,32,51,.4);
          opacity:0; transform:translateY(14px); pointer-events:none;
          transition:opacity .5s var(--soft), transform .62s var(--ease); }
.banner.on { opacity:1; transform:none; pointer-events:auto; }
.bmark { width:26px; height:26px; border-radius:8px; background:#E8F5EE; flex:none;
         display:flex; align-items:center; justify-content:center; }

.hide { display:none !important; }

/* ── the phone, where the palette turns to paper ────────────────────────────── */
@media (max-width: 760px) {
  :root {
    --canvas:#FAF8F4; --sidebar:#FCFBF8; --surface:#FFFFFF;
    --border:#E8E2D8; --hairline:rgba(30,27,22,.08); --track:rgba(30,27,22,.06);
    --text:#1E1B16; --muted:#6B6459; --dim:#9A9287; --field:#FCFBF8;
    --mine:#ECE6DE; --mine-text:#2A241D;
  }
  .rail { display:none; }
  .stream { padding:18px 18px 6px; }
  .composer { padding:10px 18px 18px; }
  .chead { padding:0 14px 0 18px; }
  .prose, .chips { max-width:none; }
  .cerin { padding:26px 18px 0; }
  .sheet { padding:20px 18px; }
  .banner { left:18px; right:18px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration:.01ms !important; animation-duration:.01ms !important; }
  .w { opacity:1; transform:none; filter:none; }
}

/* The rail is tucked away during the morning brief and slides in when the
   ceremony hands over to the ordinary panel. */
.rail.tucked { width:0; opacity:0; border-left-color:transparent; padding-left:0; padding-right:0; }

/* ── a plan rendered as a panel, because a table read out as prose is unreadable ── */
.plan { background:var(--surface); border:1px solid var(--hairline); border-radius:16px;
        padding:16px 18px; max-width:470px; margin-top:12px;
        animation:rise .46s var(--ease) both; }
.planhead { font-size:10.5px; font-weight:700; color:var(--dim); letter-spacing:.08em;
            text-transform:uppercase; margin-bottom:10px; }
.planrow { display:flex; align-items:baseline; gap:12px; padding:8px 0;
           border-top:1px solid var(--hairline); }
.planrow:first-of-type { border-top:0; padding-top:2px; }
.planwhen { width:74px; flex:none; font-size:12.5px; color:var(--muted);
            font-variant-numeric:tabular-nums; }
.planwhat { flex:1; min-width:0; font-size:13.5px; font-weight:500; }
.plandetail { font-size:12px; color:var(--dim); flex:none; }
.planfoot { font-size:12.5px; color:var(--muted); line-height:1.45; margin-top:12px;
            padding-top:10px; border-top:1px solid var(--hairline); }

/* ── the week, and task groups ── */
.dayhead { font-size:10.5px; font-weight:700; color:var(--dim); letter-spacing:.07em;
           text-transform:uppercase; margin:14px 0 4px; }
.dayhead:first-child { margin-top:0; }
.group { padding:10px 0 4px; border-top:1px solid var(--hairline); margin-top:8px; }
.group:first-of-type { border-top:0; margin-top:0; padding-top:2px; }
.grouphead { display:flex; align-items:baseline; gap:10px; }
.groupname { font-size:13.5px; font-weight:600; flex:1; min-width:0; }
.groupmeta { font-size:11.5px; color:var(--dim); margin:2px 0 4px; }
.task.child { padding-left:8px; }
.task.child .tlabel { font-size:13px; }

/* ── settings ── */
.modal { position:absolute; inset:0; z-index:30; display:flex; align-items:center;
         justify-content:center; background:rgba(22,32,51,.22); backdrop-filter:blur(1.5px);
         opacity:0; pointer-events:none; transition:opacity .32s var(--soft); }
.modal.on { opacity:1; pointer-events:auto; }
.modalbox { width:380px; background:var(--surface); border:1px solid var(--hairline);
            border-radius:20px; padding:24px 26px 20px;
            box-shadow:0 34px 70px -26px rgba(22,32,51,.45);
            transform:translateY(10px) scale(.97); transition:transform .42s var(--ease); }
.modal.on .modalbox { transform:none; }
.modalbox h2 { font-family:var(--serif); font-size:21px; font-weight:500; margin:0 0 6px;
               letter-spacing:-.015em; }
.modalbox p { font-size:12.5px; color:var(--muted); line-height:1.5; margin:0 0 16px; }
.lbl { display:block; font-size:10.5px; font-weight:700; color:var(--dim); letter-spacing:.08em;
       text-transform:uppercase; margin:0 0 6px; }
.modalbox select { width:100%; height:38px; border-radius:10px; border:1px solid var(--border);
                   background:var(--field); padding:0 10px; font-family:var(--ui);
                   font-size:13.5px; color:var(--text); margin-bottom:14px; outline:none; }
.modalbox select:focus { border-color:rgba(40,103,232,.45); background:#fff; }
.fine { font-size:12px; color:var(--muted); margin:0 0 4px; font-variant-numeric:tabular-nums; }
.modalacts { display:flex; gap:8px; justify-content:flex-end; margin-top:12px; }

/* a category tag: the colour is set inline, the shape is here */
.tag.cat { font-weight:700; letter-spacing:.04em; }

/* ── a nudge: something said without being asked ──────────────────────────── */
.nudge { display:flex; gap:10px; align-items:flex-start; max-width:470px;
         background:var(--accent-soft); border-radius:14px; padding:12px 14px;
         animation:rise .5s var(--ease) both; }
.nudgemark { flex:none; color:var(--accent); margin-top:2px; display:flex; }
.nudgetext { font-family:var(--serif); font-size:15.5px; line-height:1.5;
             letter-spacing:-.003em; color:#1B3468; text-wrap:pretty; }

/* ── the settings dialog, now that it has more than one thing in it ────────── */
.modalbox { max-height:82vh; overflow-y:auto; }
.subhead { font-size:13px; font-weight:600; margin:0 0 10px; }
.rule2 { border:0; border-top:1px solid var(--hairline); margin:18px 0 14px; }
.modalbox .row { display:flex; align-items:flex-start; gap:9px; font-size:12.5px;
                 color:var(--muted); line-height:1.45; margin-bottom:14px; cursor:pointer; }
.modalbox .row input { margin-top:1px; accent-color:var(--accent); }
.pair { display:flex; gap:10px; align-items:flex-end; margin-bottom:6px; }
.pair > div { flex:1; }
.pair input[type=text] { flex:1; min-width:0; height:38px; border-radius:10px;
                         border:1px solid var(--border); background:var(--field);
                         padding:0 10px; font-family:var(--ui); font-size:12.5px;
                         color:var(--text); outline:none; }
.pair input[readonly] { color:var(--muted); }
.pair .btn { flex:none; height:38px; }
.feedrow { display:flex; align-items:center; gap:10px; padding:7px 0;
           border-bottom:1px solid var(--hairline); }
.feedname { font-size:13px; font-weight:500; flex:1; min-width:0; }


/* ── a reminder landing ───────────────────────────────────────────────────── */
/* One line, under the header, gone in four seconds. It slides from behind the
   chrome rather than fading in place, so it reads as ARRIVING rather than as
   something that was always there and you missed. */
.notice {
  display: flex; align-items: center; gap: 9px;
  margin: 0 18px 8px; padding: 9px 13px;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: 13px; box-shadow: 0 3px 10px rgba(0,0,0,.05);
  font-size: 13.5px; color: var(--text);
  animation: noticein .34s cubic-bezier(.2,.8,.2,1);
}
.notice[hidden] { display: none; }
.notice.leaving { animation: noticeout .28s ease forwards; }
.noticebell { color: var(--accent); flex: none; }
.noticebody { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The time is the half being checked, so it never truncates. */
.noticewhen { flex: none; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
@keyframes noticein  { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
@keyframes noticeout { to { opacity: 0; transform: translateY(-8px); } }

/* ── a receipt, as opposed to a plan ──────────────────────────────────────── */
/* show_plan rows keep the original inline shape. A row the CALENDAR TOOLS wrote
   carries a second timestamp — "was Tue 8 Sep, 16:30" — which has no business
   competing with the title for one line, so those stack. */
.planrow.rk { display: block; }
/* Inline, or the date column wraps mid-date — "Thu 10 Sep," on one line and
   "15:00" on the next, which is the one thing a receipt must not do. */
.planrow.rk .planwhen {
  display: inline; margin-right: 9px; color: var(--text);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.planrow.rk .planwhat { display: inline; font-weight: 500; }
.planrow.rk .plandetail { display: block; margin-top: 2px; color: var(--dim); }
.planrow.rk-moved .plandetail { color: var(--muted); }
/* Cancelled is the one change worth colouring: it is the only one where doing
   nothing about it costs him something. The time stays and is struck through —
   for a repeating hour it is the only thing that says WHICH sitting went. */
.planrow.rk-cancelled .planwhen,
.planrow.rk-cancelled .planwhat { text-decoration: line-through; color: var(--muted); }
.planrow.rk-cancelled .plandetail { color: var(--danger); }

/* ── reminders on a day ───────────────────────────────────────────────────── */
.remlink {
  display: inline-block; margin-left: 8px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 12px; color: var(--accent); cursor: pointer;
}
.remlink:hover { text-decoration: underline; }
.rems { margin: 2px 0 10px 0; padding: 0; list-style: none; }
.rems li { display: flex; gap: 10px; padding: 5px 0; font-size: 13px; color: var(--text); }
.rems .remwhen { flex: none; min-width: 54px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rems .remwhen.allday { color: var(--dim); }
.rems li.done .rembody { text-decoration: line-through; color: var(--muted); }

/* ── the task menu ────────────────────────────────────────────────────────── */
.taskmenu {
  position: fixed; z-index: 90; min-width: 168px; padding: 5px;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.14);
}
.taskmenu button {
  display: block; width: 100%; padding: 8px 11px; border: 0; background: none;
  font: inherit; font-size: 13.5px; text-align: left; color: var(--text);
  border-radius: 8px; cursor: pointer;
}
.taskmenu button:hover { background: var(--track); }
.taskmenu button.danger { color: var(--danger); }

/* ── the day, as hours ────────────────────────────────────────────────────── */
/* The ruler and the blocks are positioned from ONE origin and ONE scale — both
   are (minutesIntoDay - rangeStart*60) / 60 * --hour. Anything that computes a
   position a second way drifts, and drift in a calendar is indistinguishable
   from the wrong time. */
.cal { --hour: 54px; --gutter: 52px; }

.calstrip { display: flex; gap: 2px; margin: 2px 0 12px; }
.calday {
  flex: 1 1 0; min-width: 0; padding: 6px 0 7px; border: 0; background: none;
  border-radius: 10px; cursor: pointer; font: inherit; text-align: center;
}
.calday:hover { background: var(--track); }
.calday .cdw { display: block; font-size: 10px; color: var(--dim); letter-spacing: .04em; }
.calday .cdn { display: block; font-size: 14px; color: var(--text); font-variant-numeric: tabular-nums; }
.calday.on { background: var(--accent-soft); }
.calday.on .cdw, .calday.on .cdn { color: var(--accent); font-weight: 600; }
.calday .cdot { display: block; width: 4px; height: 4px; margin: 3px auto 0; border-radius: 50%; background: var(--accent-pale); }
.calday .cdot.none { background: transparent; }

.calhead { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.calhead .caldate { font-family: var(--serif); font-size: 17px; color: var(--text); }
.calhead .calcount { margin-left: auto; font-size: 12px; color: var(--muted); }

.grid { position: relative; }
/* The line and its label hang off the SAME top, so the label sits on the rule
   rather than near it. */
.hline { position: absolute; left: var(--gutter); right: 0; height: 1px; background: var(--hairline); }
.hlabel {
  position: absolute; left: 0; width: calc(var(--gutter) - 10px); text-align: right;
  font-size: 11px; color: var(--dim); font-variant-numeric: tabular-nums;
  transform: translateY(-50%); white-space: nowrap;
}

.blk {
  position: absolute; overflow: hidden; border-radius: 11px; cursor: pointer;
  padding: 6px 8px 6px 10px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
}
/* The spine is drawn INSIDE the block and clipped by its radius, so the fill
   and the spine are cut by one curve rather than two that disagree. */
.blk::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: currentColor; }
.blk .bname {
  font-size: 13.5px; font-weight: 500; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.blk .bmeta {
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Under about three quarters of an hour two stacked lines do not fit, so the
   time moves up beside the title and yields first when the column is narrow. */
.blk.compact { flex-direction: row; align-items: baseline; gap: 6px; padding-top: 4px; padding-bottom: 4px; }
.blk.compact .bname { font-size: 13px; flex: 0 1 auto; }
.blk.compact .bmeta { flex: 1 1 auto; min-width: 0; }
/* Three or more abreast and there is no room for a time at all. */
.blk.tight .bmeta { display: none; }

.nowline { position: absolute; left: calc(var(--gutter) - 8px); right: 0; height: 0; pointer-events: none; }
.nowline i { position: absolute; left: 0; top: -3.5px; width: 7px; height: 7px; border-radius: 50%; background: var(--danger); }
.nowline u { position: absolute; left: 8px; right: 0; top: 0; height: 1.5px; background: var(--danger); text-decoration: none; }

.calempty { padding: 22px 2px; }
.calempty b { display: block; font-family: var(--serif); font-size: 17px; font-weight: 500; color: var(--text); }
.calempty span { display: block; margin-top: 5px; font-size: 13px; color: var(--muted); }


/* The name sits above the link: it is the shorter field and the one he will
   actually read afterwards, and side by side at rail width neither fits. */
#feedName { flex: 1 1 100%; margin-bottom: 6px; }
.feedname { border: 0; background: none; font: inherit; color: var(--text); cursor: text;
            border-radius: 6px; padding: 1px 4px; margin-left: -4px; min-width: 60px; }
.feedname:hover { background: var(--track); }
.feedname:focus { outline: 2px solid var(--accent-pale); background: var(--surface); }

/* ── the invitation ──────────────────────────────────────────────────────────
   The day, not yet started, waiting to be. Deliberately the same reading order
   as the phone's card and as the ceremony that follows it — weekday, date, the
   state of things, the way in — so that pressing the button feels like the
   strip unfolding out of the card rather than a page replacing another. */
.offer { display:flex; flex-direction:column; align-items:flex-start;
         padding:26px 26px 24px; margin-top:6px; max-width:420px;
         background:var(--surface); border:1px solid var(--hairline);
         border-radius:18px; opacity:0; transform:translateY(10px);
         transition:opacity .5s var(--ease), transform .5s var(--ease); }
.offer.on { opacity:1; transform:none; }
.offerday { font-size:11px; font-weight:700; letter-spacing:.16em; color:var(--dim); }
.offerdate { font-family:var(--serif); font-size:32px; font-weight:500;
             letter-spacing:-.022em; color:var(--text); margin-top:3px; }
.offernote { font-size:12.5px; color:var(--muted); margin-top:12px; }
.offerbtn { display:inline-flex; align-items:center; gap:9px; height:42px;
            margin-top:20px; padding:0 20px; border-radius:21px;
            background:var(--accent); color:#fff; border:0; cursor:pointer;
            font:inherit; font-size:14.5px; font-weight:600;
            transition:background .18s var(--ease), transform .12s var(--ease); }
.offerbtn:hover { background:var(--accent-hover); }
.offerbtn:active { transform:scale(.975); }

/* The group chat: his companion's messages. Her name above, and her texts in rose bubbles
   in the serif, so a glance tells the three voices apart. Texts of hers one after another stay
   under one name and share the corners where they meet. */
:root { --her:#A8466E; --her-soft:#FBF1F5; --her-pale:#E2B5C7; --her-bubble:#F6E8EE; --her-text:#2E1C25; --her-dots:#C58CA5; }
.companion { display:flex; flex-direction:column; align-items:flex-start; gap:3px; max-width:min(84%, 520px); }
.companionhead { display:flex; align-items:baseline; gap:8px; margin-bottom:1px; }
.companionname { font-size:11.5px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--her); }
.companionto { font-size:11px; color:var(--muted); }
.companiontext { max-width:100%; padding:8px 14px 9px; border-radius:16px; background:var(--her-bubble); color:var(--her-text);
                 font-family:var(--serif); font-size:15.5px; line-height:1.4; white-space:pre-wrap; overflow-wrap:anywhere; }
.companiontext + .companiontext { margin-top:1px; border-top-left-radius:5px; }
.companiontext:has(+ .companiontext) { border-bottom-left-radius:5px; }
/* Her typing, in a bubble of her own colour. Right after a text of hers it has no name
   above it and sits close: the next one coming. */
.companiontyping { display:flex; gap:5px; align-items:center; padding:12px 14px; border-radius:16px; background:var(--her-bubble); }
.companiontyping i { width:6px; height:6px; border-radius:50%; background:var(--her-dots); display:block;
                     animation:pulse 1.25s var(--ease) infinite; }
.companiontyping i:nth-child(2) { animation-delay:.16s; }
.companiontyping i:nth-child(3) { animation-delay:.32s; }
.entry.continues { margin-top:-12px; animation:typingin .2s var(--soft) both; }
@keyframes typingin { from { opacity:0; } }
.entry.continues .companiontyping { border-top-left-radius:5px; }
.entry[data-who="companion"]:has(+ .entry.continues) .companiontext:last-child { border-bottom-left-radius:5px; }

/* Who a message is to, said only when it is not the usual. */
.tolabel { font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--muted);
           margin-bottom:3px; }
.tolabel.her { color:var(--her); }
.tolabel.mineto { text-align:right; }
.toher { margin-top:10px; padding-left:12px; border-left:2px solid var(--her-pale); max-width:470px; }
.toher .prose { font-size:15.5px; }

/* Who the next message goes to. Quiet until it is not the assistant. */
.toline { display:flex; gap:4px; margin:0 0 8px 4px; }
.toline[hidden] { display:none; }
.to { height:26px; padding:0 11px; border-radius:13px; font-size:12px; color:var(--muted);
      border:1px solid transparent;
      transition:background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease), transform .12s var(--ease); }
.to:active { transform:scale(.97); }
.to[aria-pressed="true"] { background:var(--surface); border-color:var(--border); color:var(--text); font-weight:600; }
.to.her[aria-pressed="true"] { background:var(--her-soft); border-color:var(--her-pale); color:var(--her); }
@media (hover:hover) and (pointer:fine) { .to:not([aria-pressed="true"]):hover { color:var(--text); } }
