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

   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
   and the Pixel Studio. Dark is the bare :root; light overrides only
   what actually changes.
   ══════════════════════════════════════════════════════════ */
: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;
  --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=range],input[type=checkbox]{accent-color:var(--brand)}
[hidden]{display:none !important}

html{color-scheme:dark}
:root[data-theme="light"] html,html:has(: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;
}

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

/* ── bar menu ──
   Same `<details>`/`<summary>` pattern as portal, the arcade and the pixel
   editor: 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-summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.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:14rem;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}

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

/* ── privacy note ── */
.tg-privacy{max-width:1180px;margin:1rem auto 0;padding:.8rem 1rem;
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:var(--r);font-size:.86rem;color:var(--ink-dim)}
.tg-privacy strong{color:var(--ink)}

/* ── layout ── */
.tg-main{max-width:1180px;margin:0 auto;padding:1rem;
  display:grid;gap:1rem;grid-template-columns:minmax(0,360px) minmax(0,1fr);
  grid-template-areas:"sense list" "sense log";align-items:start}
.tg-sense{grid-area:sense}
.tg-list{grid-area:list}
.tg-log{grid-area:log}

.tg-sense,.tg-list,.tg-log{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:.9rem}
.tg-h{margin:0;font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint)}
.tg-list-head{display:flex;align-items:center;gap:.6rem;margin-bottom:.7rem}
.tg-list-head .tg-h{margin-right:auto}

/* ── engines ── */
.tg-engine{margin-top:.8rem;padding-top:.8rem;border-top:1px solid var(--line)}
.tg-sense .tg-engine:first-of-type{border-top:0;padding-top:.4rem}
.tg-engine-head{display:flex;align-items:center;gap:.5rem}
.tg-engine-head h3{margin:0;font-size:.95rem}
.tg-state{margin-left:auto;font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  padding:.15rem .5rem;border-radius:999px;border:1px solid var(--line);
  color:var(--ink-faint);font-weight:700}
.tg-state[data-s="live"]{color:#0b0a0d;background:var(--ok);border-color:transparent}
:root[data-theme="light"] .tg-state[data-s="live"]{color:#fff}
.tg-state[data-s="loading"]{color:var(--warn);border-color:var(--line-hot)}
.tg-state[data-s="error"]{color:var(--bad);border-color:var(--bad)}

.tg-stage{position:relative;margin:.6rem 0;background:var(--bg-2);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  aspect-ratio:4/3;display:grid;place-items:center}
.tg-stage video,.tg-stage canvas{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:none}
.tg-stage.on video,.tg-stage.on canvas{display:block}
.tg-stage canvas{pointer-events:none}
.tg-stage-msg{margin:0;padding:1rem;text-align:center;font-size:.84rem;
  color:var(--ink-faint);max-width:32ch}
.tg-stage.on .tg-stage-msg{display:none}

/* Unmistakable "we are capturing" indicator. */
.tg-stage.on::after{content:"● REC";position:absolute;top:.5rem;left:.5rem;
  background:var(--bad);color:#fff;font-size:.66rem;font-weight:800;
  letter-spacing:.1em;padding:.2rem .45rem;border-radius:4px;z-index:2}

.tg-meter{height:8px;border-radius:999px;background:var(--bg-2);
  border:1px solid var(--line);overflow:hidden;margin:.6rem 0}
.tg-meter i{display:block;height:100%;width:0;background:var(--brand);
  transition:width .08s linear}

.tg-engine-actions{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.tg-hint{font-size:.76rem;color:var(--ink-faint)}
.tg-detected{margin:.5rem 0 0;font-size:.84rem;color:var(--ink-dim)}
.tg-detected strong{color:var(--ink);font-family:var(--mono)}
.tg-conf{color:var(--ink-faint);font-size:.78rem}

.tg-adv{margin-top:.9rem;border-top:1px solid var(--line);padding-top:.7rem}
.tg-adv summary{cursor:pointer;font-size:.84rem;color:var(--ink-dim)}
.tg-field{display:flex;align-items:center;gap:.5rem;margin:.6rem 0;font-size:.82rem}
.tg-field.col{flex-direction:column;align-items:stretch}
.tg-field>span{color:var(--ink-dim);min-width:9ch}
.tg-field input[type=range]{flex:1}
.tg-field output{font-family:var(--mono);color:var(--ink);min-width:4ch;text-align:right}
.tg-check{display:flex;align-items:center;gap:.45rem;font-size:.82rem;color:var(--ink-dim)}
.tg-note{margin:.35rem 0 0;font-size:.76rem;color:var(--ink-faint)}
.tg-note.tg-warn{color:var(--warn)}
.tg-note.tg-warn strong{color:var(--bad)}

/* ── buttons ── */
.btn{appearance:none;font:inherit;font-size:.84rem;font-weight:600;cursor:pointer;
  padding:.4rem .8rem;border-radius:999px;border:1px solid var(--line);
  background:var(--surf);color:var(--ink)}
.btn:hover{border-color:var(--line-hot)}
.btn.primary{background:var(--brand);border-color:transparent;color:#1a1206}
:root[data-theme="light"] .btn.primary{color:#fff}
.btn.ghost{background:none}
.btn[disabled]{opacity:.5;cursor:not-allowed}

/* ── trigger rows ── */
.tg-row{border:1px solid var(--line);border-radius:var(--r);padding:.7rem;
  margin-bottom:.7rem;background:var(--surf)}
.tg-row[data-armed="cool"]{border-color:var(--warn)}
.tg-row[data-armed="fire"]{border-color:var(--ok)}
.tg-row-top{display:flex;gap:.45rem;align-items:center;flex-wrap:wrap}
.tg-row-top .t-url{flex:1;min-width:14ch}
.tg-arrow{color:var(--ink-faint)}
.tg-row-cfg{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:.55rem;
  font-size:.78rem;color:var(--ink-dim)}
.tg-row-cfg label{display:flex;align-items:center;gap:.35rem}
.tg-row-cfg input[type=number]{width:8.5ch}
/* 7ch clipped a 4-digit value: the 3000ms cooldown default rendered as
   "300", which misreads as a tenth of the real figure. */
.tg-row-body{margin-top:.55rem}
.tg-row-body summary{cursor:pointer;font-size:.78rem;color:var(--ink-dim)}
.tg-row-foot{display:flex;align-items:center;gap:.6rem;margin-top:.55rem}
.t-result{font-size:.78rem;color:var(--ink-faint)}
.t-result[data-r="ok"]{color:var(--ok)}
.t-result[data-r="bad"]{color:var(--bad)}
.t-result[data-r="blind"]{color:var(--warn)}

input,select,textarea{font:inherit;font-size:.84rem;color:var(--ink);
  background:var(--bg-2);border:1px solid var(--line);border-radius:8px;
  padding:.3rem .5rem;max-width:100%}
textarea{font-family:var(--mono);font-size:.78rem;width:100%;resize:vertical}

/* ── activity log ── */
.tg-log ol{list-style:none;margin:0;padding:0;max-height:16rem;overflow:auto}
.tg-log li{display:flex;gap:.6rem;align-items:baseline;padding:.35rem 0;
  border-bottom:1px solid var(--line);font-size:.8rem}
.tg-log li:last-child{border-bottom:0}
.lg-time{font-family:var(--mono);color:var(--ink-faint);font-size:.74rem;flex:none}
.lg-sig{font-weight:700;flex:none}
.lg-msg{color:var(--ink-dim);min-width:0;overflow-wrap:anywhere}
.lg-ok .lg-sig{color:var(--ok)}
.lg-bad .lg-sig{color:var(--bad)}
.lg-blind .lg-sig{color:var(--warn)}

.tg-empty{margin:.2rem 0 0;font-size:.82rem;color:var(--ink-faint)}

.tg-foot{max-width:1180px;margin:0 auto;padding:1.2rem 1rem 2rem;
  color:var(--ink-faint);font-size:.8rem;border-top:1px solid var(--line)}
.tg-foot p{margin:.2rem 0}
.tg-foot-fine{font-size:.74rem}

/* ── narrow ──
   Single column, and the sensing panel leads because you want to see the
   camera while you tune a trigger. */
@media (max-width:900px){
  .tg-main{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"sense" "list" "log"}
  .tg-row-cfg{gap:.55rem}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
}
