/* ══════════════════════════════════════════════════════════════════
   app.css — Happy Light Journal.

   Same warm-ink token set as the rest of the suite, so theme.js's
   [data-theme] switch drives this page the way it drives the arcade,
   the Pixel Studio and Triggers. Dark is the bare :root; light
   overrides only what actually changes.

   theme.js always stamps an explicit data-theme before first paint
   (resolving "auto" against the OS itself), which is why there is no
   prefers-color-scheme block here — a media query would be a second,
   competing source of truth.
   ══════════════════════════════════════════════════════════════════ */
:root{
  --bg:#0b0a0d; --bg-2:#16131a;
  --panel:rgba(29,25,34,.82); --panel-solid:#1d1922;
  --line:rgba(184,175,164,.20); --line-hot:rgba(245,158,11,.45);
  --ink:#f5f1ea; --ink-dim:#b8afa4; --ink-faint:#6b635a;
  --brand:#f59e0b; --brand-2:#a78bfa;
  --ok:#4ee8a5; --warn:#fbbf24; --bad:#f87171;
  --surf:rgba(43,37,51,.72);
  --shadow:4px 4px 0 rgba(0,0,0,.45);
  /* Logo palette. Wordmark strokes are currentColor; only the bulb
     reads these, so one asset serves both grounds. */
  --logo-glow:1; --logo-glow-color:#f59e0b; --logo-bulb:#d9a441;
  --logo-glass-hi:#fffdf6; --logo-glass-lo:#f8e3b6; --logo-face:#8a6a3b;
  --font:"Inter Variable","Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  /* A measured reading column for the preview. Prose set the full width
     of a desktop pane is genuinely harder to read. */
  --measure:34rem;
  --r:12px;
}
:root[data-theme="light"]{
  --bg:#faf8f4; --bg-2:#f1ece2;
  --panel:rgba(255,253,247,.92); --panel-solid:#fffdf7;
  --line:rgba(90,74,54,.22); --line-hot:rgba(180,83,9,.42);
  --ink:#241f18; --ink-dim:#5b5145; --ink-faint:#7d7264;
  --brand:#b45309; --brand-2:#6d28d9;
  --ok:#047857; --warn:#8c6510; --bad:#b91c1c;
  --surf:rgba(241,236,226,.80);
  --shadow:4px 4px 0 rgba(90,74,54,.22);
  /* Paper turns the bloom to haze — drop the glow, deepen the bulb. */
  --logo-glow:0; --logo-bulb:#a86f18;
  --logo-glass-hi:#fffaec; --logo-glass-lo:#f2d79c; --logo-face:#6b4d22;
}

*{box-sizing:border-box}
input[type=checkbox]{accent-color:var(--brand)}
[hidden]{display:none !important}

html{color-scheme:dark;height:100%}
:root[data-theme="light"]{color-scheme:light}

body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font);font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
  /* The app is a fixed frame with independently scrolling panes, so the
     page itself never scrolls. A flex column rather than a height
     calculation: the bar, the privacy note and the alert all change
     height (they wrap at narrow widths, and the alert comes and goes),
     and subtracting guessed constants clipped the sidebar footer.
     100dvh, not vh, so a collapsing mobile URL bar leaves no dead strip. */
  height:100dvh;
  display:flex;flex-direction:column;
  overflow:hidden;
}
.jr-bar,.jr-privacy,.jr-alert{flex:none}

a{color:var(--brand)}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
textarea:focus-visible,summary:focus-visible{
  outline:2px solid var(--brand);outline-offset:2px;border-radius:4px;
}

.skip{position:absolute;left:-9999px;top:0;background:var(--panel-solid);
  color:var(--ink);padding:.6rem .9rem;z-index:80;border-radius:0 0 var(--r) 0}
.skip:focus{left:0}

/* ── brand lockup ──
   inline-flex + column is what stacks the subtitle under the mark. It
   must stay inline-flex: the lockup is taller than its line box (the
   viewBox reserves headroom for the bulb), so as a plain inline element
   it escapes and the sticky bar clips the bulb. */
.wordmark{font-weight:700;letter-spacing:-.03em;line-height:1;
  display:inline-flex;flex-direction:column;align-items:center;gap:.3rem}
.wordmark.small{font-size:1.2rem}
.wordmark .hl-lockup{height:2em;width:auto;display:inline-block;
  color:var(--ink);flex:none}
.wm-b{color:var(--ink-dim);font-size:max(.62rem,.16em);font-weight:700;
  letter-spacing:.26em;text-indent:.26em;text-transform:uppercase;line-height:1}

/* ── top bar ── */
.jr-bar{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;
  padding:.55rem .9rem;background:var(--panel);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40}
.jr-home{text-decoration:none;flex:none}
.jr-title{font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);font-weight:600}
.jr-bar-actions{margin-left:auto;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}

.jr-btn{appearance:none;font:inherit;font-size:.82rem;cursor:pointer;
  color:var(--ink);background:var(--surf);border:1px solid var(--line);
  border-radius:999px;padding:.32rem .8rem}
.jr-btn:hover{border-color:var(--line-hot)}

.jr-seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;
  overflow:hidden;background:var(--surf)}
.jr-seg button{appearance:none;background:none;border:0;color:var(--ink-dim);
  font:inherit;font-size:.78rem;padding:.3rem .7rem;cursor:pointer}
.jr-seg button.on{background:var(--brand);color:#1a1206;font-weight:700}
:root[data-theme="light"] .jr-seg button.on{color:#fff}

/* ── bar menu ──
   Same <details>/<summary> pattern as portal, the arcade, the pixel
   editor and triggers: keyboard-operable with no custom widget; script
   only adds Escape and click-away. */
.hl-menu{position:relative}
.hl-menu-summary{display:flex;align-items:center;gap:.45rem;cursor:pointer;list-style:none;
  padding:.3rem .7rem;border:1px solid var(--line);border-radius:999px;background:var(--surf);
  color:var(--ink-dim);font-size:.78rem;user-select:none}
.hl-menu-summary::-webkit-details-marker{display:none}
.hl-menu-summary:hover{border-color:var(--line-hot);color:var(--ink)}
.hl-menu-bars{width:.85rem;height:.7rem;flex:none;
  border-top:2px solid currentColor;border-bottom:2px solid currentColor;position:relative}
.hl-menu-bars::after{content:"";position:absolute;left:0;right:0;top:calc(50% - 1px);
  border-top:2px solid currentColor}
.hl-menu-panel{position:absolute;right:0;top:calc(100% + .35rem);z-index:60;
  min-width:15rem;display:flex;flex-direction:column;padding:.3rem;
  border:1px solid var(--line);border-radius:.6rem;
  background:var(--panel-solid);box-shadow:var(--shadow)}
.hl-menu-head{margin:.45rem .55rem .2rem;font-size:.62rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint)}
.hl-menu-head:first-child{margin-top:.2rem}
.hl-menu-item{appearance:none;background:none;border:0;cursor:pointer;font:inherit;
  font-size:.85rem;color:var(--ink);text-align:left;text-decoration:none;
  padding:.45rem .55rem;border-radius:.4rem}
.hl-menu-item:hover{background:var(--line)}
.hl-menu-item:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.hl-menu-seg{margin:.15rem .55rem .3rem;align-self:flex-start}

/* ── notices ── */
.jr-privacy{margin:0;padding:.5rem .9rem;font-size:.78rem;color:var(--ink-dim);
  background:var(--bg-2);border-bottom:1px solid var(--line)}
.jr-privacy strong{color:var(--ink)}

.jr-alert{margin:0;padding:.6rem .9rem;font-size:.84rem;cursor:pointer;
  border-bottom:1px solid var(--line)}
.jr-alert.ok{background:color-mix(in srgb,var(--ok) 16%,var(--bg-2));color:var(--ink)}
.jr-alert.warn{background:color-mix(in srgb,var(--warn) 18%,var(--bg-2));color:var(--ink)}
.jr-alert.bad{background:color-mix(in srgb,var(--bad) 20%,var(--bg-2));color:var(--ink)}

/* ── frame ──
   A fixed shell with independently scrolling panes. 100dvh rather than
   vh so the mobile URL bar collapsing does not leave a dead strip. */
.jr-main{
  display:grid;
  grid-template-columns:clamp(15rem,22vw,20rem) minmax(0,1fr);
  gap:0;
  flex:1;
  min-height:0;      /* without this a grid child refuses to shrink */
}

/* ── sidebar ── */
.jr-side{display:flex;flex-direction:column;min-height:0;min-width:0;
  border-right:1px solid var(--line);background:var(--bg-2)}
.jr-side-top{padding:.6rem;border-bottom:1px solid var(--line)}
.jr-search{width:100%;font:inherit;font-size:.85rem;color:var(--ink);
  background:var(--panel-solid);border:1px solid var(--line);
  border-radius:999px;padding:.4rem .8rem}
.jr-search::placeholder{color:var(--ink-faint)}

.jr-list{list-style:none;margin:0;padding:.35rem;overflow-y:auto;flex:1;min-height:0}
.jr-item{display:flex;align-items:stretch;gap:.2rem;border-radius:.5rem;margin-bottom:.15rem}
.jr-item:hover{background:var(--surf)}
.jr-item.on{background:var(--surf);box-shadow:inset 2px 0 0 var(--brand)}
.jr-item-open{appearance:none;background:none;border:0;cursor:pointer;font:inherit;
  color:var(--ink);text-align:left;flex:1;min-width:0;
  display:grid;gap:.1rem;padding:.45rem .5rem;border-radius:.5rem}
.jr-item-title{font-weight:600;font-size:.88rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jr-item-prev{font-size:.76rem;color:var(--ink-faint);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jr-item-when{font-size:.68rem;color:var(--ink-faint);letter-spacing:.04em}
.jr-item-del{appearance:none;background:none;border:0;cursor:pointer;
  color:var(--ink-faint);font-size:1.1rem;line-height:1;padding:0 .5rem;
  border-radius:.4rem;opacity:0}
.jr-item:hover .jr-item-del,.jr-item-del:focus-visible{opacity:1}
.jr-item-del:hover{color:var(--bad)}

.jr-list-empty{margin:0;padding:1rem .8rem;font-size:.82rem;color:var(--ink-faint)}

.jr-side-foot{padding:.5rem .6rem;border-top:1px solid var(--line);
  display:grid;gap:.15rem;font-size:.7rem;color:var(--ink-faint)}
.jr-count{font-weight:600;color:var(--ink-dim)}
.jr-usage{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.jr-usage.warn{color:var(--warn);font-weight:600}

/* ── work area ──
   data-view drives which panes exist. Using grid-template-columns
   rather than display:none keeps the textarea's scroll position and
   undo history intact across a view switch. */
.jr-work{display:grid;min-width:0;min-height:0}
.jr-work[data-view="split"]{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.jr-work[data-view="edit"]{grid-template-columns:minmax(0,1fr)}
.jr-work[data-view="read"]{grid-template-columns:minmax(0,1fr)}
.jr-work[data-view="edit"] .jr-pane-read{display:none}
.jr-work[data-view="read"] .jr-pane-edit{display:none}

.jr-pane{min-width:0;min-height:0;display:flex;overflow:hidden}
.jr-pane-edit{border-right:1px solid var(--line)}
.jr-work[data-view="edit"] .jr-pane-edit{border-right:0}

.jr-editor{
  flex:1;min-width:0;width:100%;resize:none;
  font-family:var(--mono);font-size:14px;line-height:1.7;
  color:var(--ink);background:var(--bg);border:0;outline-offset:-3px;
  padding:1rem clamp(.8rem,2.5vw,1.6rem);
  overflow-y:auto;
  tab-size:2;
}
.jr-editor::placeholder{color:var(--ink-faint)}

.jr-pane-read{overflow-y:auto}
#preview{padding:1rem clamp(.8rem,2.5vw,1.6rem);max-width:var(--measure);
  width:100%;margin:0 auto}

/* ── drop overlay ── */
.jr-drop{position:fixed;inset:0;z-index:70;display:grid;place-items:center;
  background:color-mix(in srgb,var(--bg) 78%,transparent);
  backdrop-filter:blur(2px);pointer-events:none}
.jr-drop span{border:2px dashed var(--brand);border-radius:var(--r);
  padding:1.2rem 1.6rem;font-weight:600;color:var(--ink);
  background:var(--panel-solid);text-align:center;max-width:min(90vw,28rem)}
.jr-drop code{font-family:var(--mono);font-size:.9em}

/* ══════════════════════════════════════════════════════════════════
   RENDERED MARKDOWN
   ══════════════════════════════════════════════════════════════════ */

.md{overflow-wrap:break-word}
.md > :first-child{margin-top:0}
.md > :last-child{margin-bottom:0}

.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{
  line-height:1.25;margin:1.6em 0 .5em;font-weight:700;letter-spacing:-.01em}
.md h1{font-size:1.7rem}
.md h2{font-size:1.35rem;padding-bottom:.25rem;border-bottom:1px solid var(--line)}
.md h3{font-size:1.12rem}
.md h4{font-size:1rem}
.md h5,.md h6{font-size:.9rem;color:var(--ink-dim);text-transform:uppercase;letter-spacing:.08em}

.md p{margin:0 0 .9em}
.md strong{font-weight:700;color:var(--ink)}
.md em{font-style:italic}
.md del{color:var(--ink-faint)}

.md hr{border:0;border-top:1px solid var(--line);margin:1.8em 0}

.md ul,.md ol{margin:0 0 .9em;padding-left:1.4em}
.md li{margin:.2em 0}
.md .md-loose > li{margin:.6em 0}
/* Only the task items drop their marker. Putting list-style:none on the
   whole <ul> stripped the bullets from plain siblings in a mixed list —
   visible on the welcome note, where "Bullet lists, nested:" lost its
   bullet because two items further down were checkboxes. */
.md li.md-task{list-style:none;display:flex;gap:.5em;align-items:flex-start}
.md .md-tasklist{padding-left:1.15em}
.md li.md-task > input{margin-top:.35em;flex:none}

.md blockquote{margin:0 0 .9em;padding:.1em 0 .1em 1em;
  border-left:3px solid var(--brand);color:var(--ink-dim)}
.md blockquote > :last-child{margin-bottom:0}

.md code{font-family:var(--mono);font-size:.88em;
  background:var(--surf);border:1px solid var(--line);
  border-radius:.3em;padding:.1em .35em}
.md pre{margin:0 0 1em;padding:.8rem 1rem;overflow-x:auto;
  background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r)}
.md pre code{background:none;border:0;padding:0;font-size:.85em;line-height:1.6}
/* The language label, from the fence's info string. */
.md pre[data-lang]{position:relative;padding-top:1.5rem}
.md pre[data-lang]::before{content:attr(data-lang);position:absolute;top:.3rem;right:.6rem;
  font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint)}

/* A wide table scrolls inside its own box — the page never does. */
.md-table-wrap{overflow-x:auto;margin:0 0 1em;
  border:1px solid var(--line);border-radius:var(--r)}
.md table{border-collapse:collapse;width:100%;font-size:.9rem}
.md th,.md td{padding:.45rem .7rem;border-bottom:1px solid var(--line);text-align:left}
.md th{background:var(--surf);font-weight:700;white-space:nowrap}
/* Column alignment from the table's delimiter row. Classes rather than
   inline styles, so the CSP needs no 'unsafe-inline' for style-src. */
.md .md-al-left{text-align:left}
.md .md-al-center{text-align:center}
.md .md-al-right{text-align:right}
.md tbody tr:last-child td{border-bottom:0}

/* ── embedded media ── */
.md-img,.md-video{max-width:100%;height:auto;display:block;
  border-radius:var(--r);border:1px solid var(--line);margin:.4em 0}
.md-audio{margin:.6em 0;display:grid;gap:.25rem}
.md-audio audio{width:100%;max-width:100%}
.md-audio figcaption{font-size:.75rem;color:var(--ink-faint)}

.md-media-loading{display:inline-block;font-size:.8rem;color:var(--ink-faint);
  background:var(--surf);border:1px dashed var(--line);
  border-radius:.4em;padding:.2em .5em}

/* A reference whose blob is gone — said plainly rather than shown as a
   broken image icon. */
.md-missing{display:inline-block;font-size:.8rem;color:var(--warn);
  background:color-mix(in srgb,var(--warn) 12%,transparent);
  border:1px dashed var(--warn);border-radius:.4em;padding:.2em .5em}

/* A destination the sanitiser refused. Shown, not silently dropped. */
.md-blocked{color:var(--ink-dim);text-decoration:line-through wavy var(--bad)}
.md-blocked-tag{margin-left:.35em;font-size:.68rem;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;text-decoration:none;
  color:var(--bad);border:1px solid var(--bad);border-radius:.3em;padding:0 .3em;
  cursor:help}

/* ══════════════════════════════════════════════════════════════════
   NARROW
   Below this width "split" cannot honestly show two columns, so the
   panes stack and each gets its own scroll. The user's chosen view is
   not silently changed — the layout adapts to it.
   ══════════════════════════════════════════════════════════════════ */
@media (max-width:860px){
  .jr-main{
    grid-template-columns:minmax(0,1fr);
    grid-template-rows:auto minmax(0,1fr);
  }
  .jr-side{border-right:0;border-bottom:1px solid var(--line);max-height:38vh}
  .jr-work[data-view="split"]{
    grid-template-columns:minmax(0,1fr);
    grid-template-rows:minmax(8rem,1fr) minmax(8rem,1fr);
  }
  .jr-work[data-view="split"] .jr-pane-edit{
    border-right:0;border-bottom:1px solid var(--line);
  }
  .jr-privacy{font-size:.72rem}
  #preview{max-width:none}
}

@media (max-width:540px){
  .jr-bar{gap:.5rem;padding:.5rem .8rem}
  .jr-title{display:none}          /* the wordmark already says "Journal" */
  .jr-bar-actions{width:100%;margin-left:0;justify-content:space-between}
  .jr-seg button{padding:.3rem .55rem;font-size:.74rem}
  .jr-side{max-height:32vh}
}

/* Someone who asked for less motion gets no transitions from us. */
@media (prefers-reduced-motion:reduce){
  *{transition:none !important;animation:none !important}
}
