/*! taildash — app sheet.
 *  Builds on the vendored mail-triage design system (app/static/design/).
 *  System files stay verbatim; app-specific components live here, composed
 *  from the system's tokens (base.css :root). No new palette. */

/* ---------------------------------------------------------------- shell --
 * This app has no sidebar, so: zero the sidebar offset and make the topbar
 * an always-on header (the system's .topbar is phone-only by default). */
.main{margin-left:0}
.topbar{display:flex;align-items:center;gap:12px;position:sticky;top:0;z-index:30;
  background:rgba(250,250,250,.94);backdrop-filter:blur(6px);
  border-bottom:1px solid var(--line);padding:10px 14px;
  padding-top:calc(env(safe-area-inset-top) + 10px)}
.topbar .tb-status{margin-left:auto;display:flex;align-items:center;gap:7px;color:var(--dim);font-size:.78rem}
.topbar .brand{flex:none}
.content{max-width:1000px}

/* ----------------------------------------------------------- tab chips -- */
.td-tabs{gap:6px}
.td-tabs .chip{font-family:inherit}  /* button reset: chips inherit Geist */
@media (pointer:coarse){.td-tabs .chip{height:44px;padding:0 16px}}

/* ------------------------------------------------------------ task card -- */
.td-card .td-title{margin:0;font-size:.98rem;overflow-wrap:anywhere;min-width:0}
.td-card .card-h{align-items:flex-start}

/* progress: tqdm-style bar + right-aligned percent */
.td-progrow{display:flex;align-items:center;gap:12px;margin-top:12px}
.td-progrow .progress{flex:1;height:8px}
.td-pct{font-family:var(--mono);font-size:.84rem;font-weight:600;font-variant-numeric:tabular-nums;
  min-width:44px;text-align:right}
.td-steps{margin-top:6px;font-variant-numeric:tabular-nums}

/* status colour on the bar (always paired with the text badge) */
.status-running   .progress i{background:var(--ok)}
.status-stalled   .progress i{background:var(--warn)}
.status-completed .progress i{background:var(--ok)}
.status-failed    .progress i{background:var(--err)}

/* unknown total: always-visible shimmer that never reads as "empty"
   (running: marching stripes of green; stalled: same texture, frozen) */
.progress i.indet{
  width:100%;
  background:linear-gradient(90deg,rgba(6,122,70,.2),rgba(6,122,70,.8),rgba(6,122,70,.2));
  background-size:40% 100%;background-repeat:repeat-x}
.status-running .progress i.indet{animation:td-shimmer 1.3s linear infinite}
.status-stalled .progress i.indet{opacity:.45}
@keyframes td-shimmer{from{background-position:0 0}to{background-position:-40% 0}}

/* finished cards are compact: no bar, keep the step count line */
.status-completed .td-progrow,.status-failed .td-progrow{display:none}

.td-msg{margin-top:10px;font-size:.92rem;overflow-wrap:anywhere;white-space:pre-wrap}
.td-err{margin:12px 0 0}

/* meta row: label + tabular value pairs */
.td-metarow{gap:6px 18px;margin-top:12px}
.td-mi{display:inline-flex;align-items:baseline;gap:6px;font-size:.84rem}
.td-mi .k{color:var(--dim)}
.td-mi b{font-weight:600;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}

/* actions */
.td-actions{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-top:14px}
.td-logs .n{font-family:var(--mono);font-size:.74rem;font-weight:400;color:var(--dim)}
.td-dismiss svg{width:14px;height:14px;display:block}
.td-dismiss.armed,.td-dismiss.armed:hover{background:var(--err);border-color:var(--err);color:#fff}

/* log console: system .logpanel, capped + scrollable inside the card */
.td-console{position:relative;margin-top:12px}
.td-console .logpanel{max-height:280px;overflow:auto;padding:10px 12px}
.td-console .lmsg{white-space:pre-wrap}
.td-console .td-more{color:#8f8f8f;font-size:.76rem}
.td-jump{position:absolute;right:10px;bottom:10px;background:#fff;
  box-shadow:0 4px 14px rgba(0,0,0,.15);opacity:0;pointer-events:none;transition:opacity .15s}
.td-jump.on{opacity:1;pointer-events:auto}

/* -------------------------------------------------------- topbar tools -- */
/* Display tools: fullscreen, pixel wipe, OLED toggle. Compact icon buttons;
   the OLED button is a two-state toggle (dark theme + pixel shift). */
.tb-tools{display:flex;gap:6px;margin-left:10px;flex:none}
.tb-btn{width:30px;height:30px;min-width:30px;min-height:30px;padding:0;color:var(--dim)}
.tb-btn svg{width:15px;height:15px}
.tb-btn:hover{color:var(--fg);border-color:var(--line2)}
.tb-btn.on{background:#000;border-color:#000;color:#fff}
@media (pointer:coarse){
  .tb-btn{width:38px;height:38px;min-width:38px;min-height:38px}
  .tb-btn svg{width:17px;height:17px}
}
@media (max-width:560px){
  .topbar #conn-text{display:none}  /* dot-only status frees room for the tools */
}

/* ----------------------------------------------------- OLED burn-in mode -- */
/* True-black theme: background pixels are OFF, text is dimmed (wear tracks
   luminance), accents keep their hue at lower brightness. Toggled by the
   moon button; pairs with pixel shift below. */
html.oled{color-scheme:dark;
  --bg:#000;--card:#000;--card2:#0d0d0d;--line:#232323;--line2:#343434;
  --fg:#c9c9c9;--dim:#7f7f7f;
  --acc:#5c9dff;--ok:#2eb872;--warn:#d29a3a;--err:#e05b60;
  --tint-acc:#0b1220;--tint-ok:#081510;--tint-warn:#181106;--tint-err:#1c0b0c;
  --hover:#0d0d0d;--active:#161616;--focus:rgba(92,157,255,.4);
  --codebg:#000;--codefg:#b8b8b8;--panel:#000;--panel-dim:#6f6f6f}
html.oled body{background:#000}
html.oled .topbar{background:rgba(0,0,0,.92)}
html.oled .brand-mark{background:#242424;color:#bdbdbd}
html.oled .btn,html.oled .badge,html.oled .chip,html.oled .iconbtn,
html.oled input,html.oled select,html.oled textarea,
html.oled .msg,html.oled .menu-pop,html.oled .copy{background:#000}
html.oled .btn.primary,html.oled .badge.solid{background:#d9d9d9;border-color:#d9d9d9;color:#000}
html.oled .chip.active{background:#202020;border-color:#4a4a4a;color:#e5e5e5}
html.oled .progress{background:#0d0d0d;border-color:#232323}
html.oled .empty h4{color:var(--fg)}
html.oled .td-jump{background:#0d0d0d}
html.oled .toast2{background:#0d0d0d}

/* pixel shift: the whole board drifts a few px on a rotating pattern so no
   column of pixels carries the same content forever (the firmware/kiosk
   approach). Offsets stay <= 0 on both axes — negative translations never
   grow the page's scrollable area — and integral, so text stays crisp. */
html.oled-shift{overflow-x:hidden}
html.oled-shift body{transition:transform 2.4s ease;will-change:transform}

/* pixel wipe: a full-screen sweep of saturated RGB bars, then a white and a
   black reset — every subpixel is driven hard and released. Manual, via the
   refresh button; tap anywhere to skip. */
.td-wipe{position:fixed;inset:-12px;z-index:400;cursor:default}
.td-wipe .td-bars{position:absolute;inset:0;
  background:linear-gradient(90deg,#f00 0 33.3%,#0f0 33.3% 66.6%,#00f 66.6% 100%);
  background-size:300% 100%;animation:td-sweep 2.4s linear both}
.td-wipe.flash{background:#fff}
.td-wipe.flash .td-bars,.td-wipe.dark .td-bars{display:none}
.td-wipe.dark{background:#000}
@keyframes td-sweep{from{background-position:0 0}to{background-position:100% 0}}

/* ------------------------------------------------- mobile card compaction -- */
/* Phones: same card, tightened in place. The bar, percent and step count
   share one row (display:contents lifts the steps line up), the meta row
   collapses to a dim values-only line, messages clamp to 2 lines, spacing
   drops to a 4/8 rhythm, and secondary actions become icon-only while the
   buttons keep their 44px touch height on coarse pointers. */
@media (max-width:767px){
  .td-card{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:6px 8px;
    align-items:center;padding:10px 12px;margin:10px 0}
  .td-card .card-h{grid-column:1/-1;margin:0}
  .td-card .td-title{font-size:.92rem}
  .td-card .badge{font-size:.64rem;padding:1px 5px}
  .td-card:not(.status-completed):not(.status-failed) .td-progrow{display:contents}
  .td-card .progress{grid-column:1;grid-row:2;height:6px}
  .td-card .td-pct{grid-column:2;grid-row:2;font-size:.76rem;min-width:34px}
  .td-card .td-pct:empty{min-width:0}
  .td-card .td-steps{grid-column:3;grid-row:2;margin:0;font-size:.74rem;text-align:right}
  .status-completed .td-steps,.status-failed .td-steps{grid-column:1;grid-row:2;text-align:left}
  .td-card .td-msg{grid-column:1/-1;margin:0;font-size:.86rem;display:-webkit-box;
    -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .td-card .td-err{grid-column:1/-1;margin:0}
  .td-card .td-metarow{grid-column:1/-1;margin:0;gap:2px 12px}
  .td-card .td-mi{font-size:.78rem}
  .td-card .td-mi .k{display:none}  /* values only: "12m · 2s ago · agent · host" */
  .td-card .td-mi + .td-mi::before{content:"·";color:var(--dim)}
  .td-card .td-actions{grid-column:1/-1;margin:8px 0 0}
  .td-card .td-actions .btn{font-size:0;gap:0;padding:0 11px}
  .td-card .td-actions .btn::before{content:"";width:16px;height:16px;flex:none;
    background-color:currentColor;
    -webkit-mask:var(--td-icon) center/contain no-repeat;mask:var(--td-icon) center/contain no-repeat}
  .td-card .td-logs{--td-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 17l6-6-6-6M12 19h8'/%3E%3C/svg%3E")}
  .td-card .td-dismiss{--td-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16M10 7V5h4v2m-6 0 1 13h6l1-13M10 11v6M14 11v6'/%3E%3C/svg%3E")}
  .td-card .td-dismiss.armed::before{display:none}  /* armed swaps in the real svg */
  .td-card .td-logs .n{font-size:.7rem;margin-left:5px}
  .td-card .td-console{grid-column:1/-1;margin:8px 0 0}
  .td-card .td-console .logpanel{max-height:200px}
}
