/* ══════════════════════════════════════════════════════════════════════════
   THE FORGE — shared design system
   ─────────────────────────────────────────────────────────────────────────
   Direction: hot metal on cold steel.

   The chrome is cold: graphite plate, steel hairlines, nothing decorative.
   Heat is the scarce resource. The ember accent marks only the active nav
   item, running work, and primary actions. If something glows here,
   something is happening.

   This file owns tokens, base styles, layout scaffolding, and the shared
   component set. Per-page rules live in frontend/static/pages/*.css.
   Token names are a superset of the historical set — nothing was renamed.
   ══════════════════════════════════════════════════════════════════════════ */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

/* ══ 1. TOKENS ═══════════════════════════════════════════════════════════ */

:root{
  /* ── Plate: the cold base. Four graphite steps, not "cards on black". */
  --bg:#0a0b0d;
  --bg2:#101216;
  --bg3:#15181d;
  --bg4:#1e2229;
  --bg-secondary:var(--bg2);
  --bg-card:#15181d;
  --bg-elevated:#1e2229;
  --bg-hover:#1e2229;
  --bg-input:#08090b;

  /* ── Ink */
  --text:#e7e9ec;
  --text-bright:#ffffff;
  --text-dim:#a0a8b4;
  --text-dim2:#7a8391;
  --text-dim-more:var(--text-dim2);

  /* ── Hairlines. Steel, never pure white — white borders read as plastic. */
  --border:rgba(150,168,190,0.16);
  --border-focus:rgba(255,106,43,0.55);
  --glass-border:rgba(150,168,190,0.16);
  --glass-border-hover:rgba(150,168,190,0.32);

  /* ── Heat. One accent, used sparingly. */
  --accent:#ff6a2b;
  --accent2:#ffb545;
  --accent-dark:#bf5020;
  --accent-glow:rgba(255,106,43,0.28);
  --accent-rgb:255,106,43;
  --accent2-rgb:255,181,69;
  --orange-rgb:255,143,63;
  --cyan-rgb:92,201,216;
  --purple:#a88bff;
  --pink:#f472b6;
  --orange:#ff8f3f;
  /* Ink that sits on top of an ember fill — the one non-token colour, kept
     so filled buttons stay legible against the light end of the gradient. */
  --on-accent:#0b0b0f;

  /* ── Instrument colours. Reserved for data and state, never decoration. */
  --cyan:#5cc9d8;
  --green:#58d27a;
  --amber:#e6a93c;
  --red:#f2555a;

  /* ── Aliases kept for pages that predate the token cleanup. */
  --accent-glow-strong:rgba(255,106,43,0.45);
  --btn-enabled-glow:0 0 0 1px rgba(255,106,43,0.28),0 2px 12px rgba(255,106,43,0.16);
  --btn-disabled-opacity:0.45;

  /* ── Surfaces: translucent fills that sit on the plate. */
  --surface:rgba(150,168,190,0.06);
  --surface-hover:rgba(150,168,190,0.12);
  --surface-active:rgba(150,168,190,0.18);
  --glass-bg:#15181d;
  --glass-blur:0px;

  /* Skeleton shimmer highlights. Dark plate uses white glints; the light
     themes override these so skeletons stay pale, never black. */
  --shimmer-lo:rgba(255,255,255,0.04);
  --shimmer-hi:rgba(255,255,255,0.10);

  /* ── Elevation. Shadow plus a hairline, so edges survive on dark plate. */
  --shadow-sm:0 1px 2px rgba(0,0,0,0.55),0 0 0 1px rgba(150,168,190,0.07);
  --shadow-md:0 6px 22px rgba(0,0,0,0.50),0 0 0 1px rgba(150,168,190,0.09);
  --shadow-lg:0 16px 50px rgba(0,0,0,0.60),0 0 0 1px rgba(150,168,190,0.11);
  --shadow-card:var(--shadow-sm);
  --shadow-hover:var(--shadow-md);

  /* ── Geometry. Four steps, on an 4px grid: chip → control → card → panel.
        Every radius in the app resolves to one of these. */
  --radius-xs:4px;
  --radius-sm:8px;
  --radius:12px;
  --radius-lg:16px;
  --radius-pill:999px;

  /* ── Rhythm. A single 4px scale under everything. */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:24px; --sp-6:32px; --sp-7:48px;

  /* ── Structure */
  --sidebar-w:224px;
  --topbar-h:44px;
  --toolbar-h:40px;
  --status-h:26px;
  --tab-h:34px;
  --thumb-size:120px;
  --mobile-nav-h:56px;
  /* Android's WebView does not populate env(safe-area-inset-*). The Forge Net
     shell measures the real insets natively and sets --android-inset-* on the
     root element instead, so prefer those and fall back to the standard env()
     values in a normal browser or iOS. */
  --safe-b:var(--android-inset-bottom,env(safe-area-inset-bottom,0px));
  --safe-t:var(--android-inset-top,env(safe-area-inset-top,0px));
  --safe-l:var(--android-inset-left,env(safe-area-inset-left,0px));
  --safe-r:var(--android-inset-right,env(safe-area-inset-right,0px));

  /* ── Type. Body is the native UI grotesque; data and labels are mono.
        No webfont is shipped, so these resolve to the platform's own faces —
        a deliberate choice that keeps the first paint instant and the app
        fully offline-capable. */
  --font-sans:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI Variable','Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --font-mono:'JetBrains Mono','SF Mono','Cascadia Mono','Fira Code','Roboto Mono',ui-monospace,'Liberation Mono',Menlo,Consolas,monospace;
  --font-display:var(--font-sans);

  --fs-xs:10px;
  --fs-sm:11px;
  --fs-base:13px;
  --fs-md:14px;
  --fs-lg:16px;
  --fs-xl:20px;
  --fs-2xl:26px;

  /* ── Motion. --tr-ui is the standard interactive transition for every
        control that tints on hover; it replaces the hand-written property
        lists that used to be pasted into each rule. */
  --ease:cubic-bezier(.2,.8,.3,1);
  --dur-fast:120ms;
  --dur:200ms;
  --dur-slow:320ms;
  --tr-ui:color var(--dur-fast) var(--ease),background-color var(--dur-fast) var(--ease),
          border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease),
          opacity var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease),
          filter var(--dur-fast) var(--ease),fill var(--dur-fast) var(--ease),
          stroke var(--dur-fast) var(--ease);

  /* ── Stacking order. One scale, so nothing fights with a hardcoded number. */
  --z-bg:0;
  --z-page:1;
  --z-topbar:60;
  --z-backdrop:110;
  --z-rail:120;
  --z-drawer:130;
  --z-overlay:300;
  --z-modal:9998;
  --z-toast:99999;
}

/* ══ 2. BASE ═════════════════════════════════════════════════════════════ */

html{
  font-family:var(--font-sans);
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
  scrollbar-color:var(--border) transparent;
}

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-sans);
  font-size:var(--fs-base);
  line-height:1.5;
  letter-spacing:0;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  display:flex;
  flex-direction:column;
  min-height:100vh;
  min-height:100dvh;
  overscroll-behavior-y:none;
  padding-left:var(--safe-l);
  padding-right:var(--safe-r);
}

/* The heat line. A single hairline at the foot of every page, dark until the
   app marks itself busy — the one piece of ambient state in the chrome. */
body::after{
  content:'';
  position:fixed;
  left:0;right:0;bottom:0;
  height:2px;
  z-index:100;
  pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--accent-dark),var(--accent),var(--accent2),transparent);
  opacity:.20;
  transition:opacity var(--dur-slow) var(--ease);
}

h1,h2,h3,h4,h5{font-family:var(--font-display);font-weight:600;letter-spacing:-.015em;color:var(--text);line-height:1.25}
h1{font-size:var(--fs-2xl);letter-spacing:-.025em}
h2{font-size:var(--fs-xl)}
h3{font-size:var(--fs-lg)}
h4{font-size:var(--fs-md)}
h5{font-size:var(--fs-base)}

a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:2px}

/* Nothing overflows its container horizontally. This is the single biggest
   fix for the Android WebView wrapper. */
img,svg,video,canvas,iframe{max-width:100%}
img,video{height:auto}

code,kbd,samp,pre{font-family:var(--font-mono);font-size:0.92em;font-variant-ligatures:none}
code{background:var(--surface);border-radius:var(--radius-xs);padding:1px 5px;color:var(--text)}
pre{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px;overflow-x:auto;line-height:1.55}
pre code{background:none;padding:0}
kbd{
  font-size:var(--fs-xs);background:var(--bg3);border:1px solid var(--border);
  border-bottom-width:2px;border-radius:var(--radius-xs);padding:2px 5px;color:var(--text-dim);
}

hr{border:none;border-top:1px solid var(--border);margin:var(--sp-4) 0}
::selection{background:var(--accent-glow);color:var(--text-bright)}

/* Tabular numerals everywhere numbers matter — money, sizes, seeds, timings. */
.num,.mono,td.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums}

/* The instrument label. Section headers, table headings, meta rows. */
.label,.forge-section-label{
  font-family:var(--font-mono);
  font-size:var(--fs-xs);
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.10em;
  color:var(--text-dim2);
}

/* Section header: the label voice plus a trailing steel hairline. One rule for
   every page — dashboard, finance, mint, work and videos all used to roll their
   own weight/tracking/margin. */
.section-title,.sec-title,.vid-section-title{
  font-family:var(--font-mono);
  font-size:var(--fs-xs);
  font-weight:600;
  text-transform:uppercase;
  letter-spacing:.08em;
  color:var(--text-dim2);
  margin:var(--sp-4) 0 var(--sp-2);
  display:flex;align-items:center;gap:8px;
}
.section-title:first-child,.section-title:first-of-type,
.sec-title:first-child,.vid-section-title:first-child{margin-top:0}
.section-title::after,.sec-title::after,.vid-section-title::after{
  content:'';flex:1;height:1px;background:var(--border);
}

/* ══ 3. LAYOUT ═══════════════════════════════════════════════════════════ */

.sidebar{
  /* The rail's own width is fixed (not var(--sidebar-w)): --sidebar-w is the
     layout offset token that surrounding pages use. When the rail collapses,
     the token goes to zero so every page reflows together, while the rail
     itself keeps this standing width so it still slides as one panel. */
  position:fixed;top:0;left:0;bottom:0;width:224px;z-index:var(--z-rail);
  display:flex;flex-direction:column;
  background:var(--bg2);
  border-right:1px solid var(--border);
  transition:transform var(--dur) var(--ease);
  padding-top:var(--safe-t);
  padding-bottom:var(--safe-b);
}

.sidebar-brand{
  display:flex;align-items:center;gap:10px;
  padding:0 16px;height:var(--topbar-h);flex-shrink:0;
  font-size:var(--fs-md);font-weight:650;letter-spacing:-.02em;
  color:var(--text);text-decoration:none;
  border-bottom:1px solid var(--border);
}
.sidebar-brand:hover{text-decoration:none}
.sidebar-brand svg,.sidebar-brand img{width:20px;height:20px;display:block;flex-shrink:0}
/* The ember mark glows with the theme's heat; the light plate stays clean. */
.sidebar-brand img.brand-icon{filter:drop-shadow(0 2px 10px var(--accent-glow))}
html[data-forge-theme="light"] .sidebar-brand img.brand-icon,
html[data-forge-theme="frutigeraero"] .sidebar-brand img.brand-icon,
html[data-forge-theme="wii"] .sidebar-brand img.brand-icon{filter:none}
.sidebar-brand .accent{
  background:linear-gradient(100deg,var(--accent),var(--accent2));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
}

.sidebar-nav{
  flex:1;overflow-y:auto;overflow-x:hidden;
  display:flex;flex-direction:column;gap:1px;
  padding:var(--sp-2) var(--sp-2) var(--sp-3);
  scrollbar-width:none;
}
.sidebar-nav::-webkit-scrollbar{display:none}

.sidebar-nav .nav-group{
  font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:500;
  text-transform:uppercase;letter-spacing:.12em;color:var(--text-dim2);
  padding:14px 12px 6px;
}
.sidebar-nav .nav-group:first-child{padding-top:6px}

/* Nav row. The active marker is the signature: a 3px ember bar flush to the
   rail's left edge, with just enough bloom to read as heat. */
.sidebar-nav a{
  position:relative;
  display:flex;align-items:center;gap:10px;
  padding:0 12px;min-height:36px;
  border-radius:var(--radius-sm);
  font-size:var(--fs-base);font-weight:500;
  color:var(--text-dim);text-decoration:none;
  transition:color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
  white-space:nowrap;overflow:hidden;
}
/* With six groups the rail would scroll on a laptop screen. Mouse users get tighter rows; touch keeps
   the full 36px target. */
@media (hover:hover) and (pointer:fine){
  .sidebar-nav a{min-height:30px}
  .sidebar-nav .nav-group{padding:10px 12px 4px}
  .sidebar-nav .nav-group:first-child{padding-top:4px}
}
.nav-icon{width:16px;height:16px;flex-shrink:0;display:block}
.sidebar-nav a .nav-icon{opacity:.75}
.sidebar-nav a:hover{color:var(--text);background:var(--surface);text-decoration:none}
.sidebar-nav a:hover .nav-icon{opacity:1}
.sidebar-nav a.active{color:var(--text-bright);background:var(--surface)}
.sidebar-nav a.active .nav-icon{opacity:1;color:var(--accent)}
.sidebar-nav a.active::before{
  content:'';position:absolute;left:-8px;top:50%;transform:translateY(-50%);
  width:3px;height:18px;border-radius:0 var(--radius-xs) var(--radius-xs) 0;
  background:linear-gradient(180deg,var(--accent2),var(--accent));
  box-shadow:0 0 10px var(--accent-glow);
}
.sidebar-nav .nav-sep{height:1px;background:var(--border);margin:var(--sp-2) var(--sp-2);flex-shrink:0}

/* Nav rows are draggable — reorder like launcher cards, saved site-wide */
.sidebar-nav a{cursor:grab}
.sidebar-nav a:active{cursor:grabbing}
body.nav-dragging .sidebar-nav a{cursor:grabbing;user-select:none;-webkit-user-select:none}
.sidebar-nav a.dragging{
  position:fixed;z-index:100;
  background:var(--bg-elevated);border:1px solid var(--border-focus);
  box-shadow:var(--shadow-md);
  will-change:transform;
}
/* Once the user has a custom order, the group labels lose their meaning */
.sidebar-nav.custom .nav-group{display:none}

.sidebar-bottom{
  padding:var(--sp-2);border-top:1px solid var(--border);flex-shrink:0;
  display:flex;flex-direction:column;gap:var(--sp-1);
}
.sidebar-bottom .rocket-link,.topbar .rocket-link{
  display:flex;align-items:center;justify-content:center;gap:7px;
  min-height:34px;padding:0 12px;border-radius:var(--radius-sm);
  font-size:var(--fs-sm);font-weight:600;
  color:var(--text-dim);background:var(--surface);
  border:1px solid var(--border);
  text-decoration:none;transition:var(--tr-ui);
}
.sidebar-bottom .rocket-link span,.topbar .rocket-link span{white-space:nowrap}
.sidebar-bottom .rocket-link:hover,.topbar .rocket-link:hover{
  background:var(--surface-hover);color:var(--text);border-color:var(--glass-border-hover);text-decoration:none;
}

.sidebar-toggle{
  position:fixed;top:calc(var(--safe-t) + 6px);left:8px;z-index:var(--z-drawer);
  width:36px;height:36px;border-radius:var(--radius-sm);
  background:var(--bg2);border:1px solid var(--border);
  color:var(--text-dim);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:var(--tr-ui);
  font-size:16px;line-height:1;
}
.sidebar-toggle:hover{background:var(--surface-hover);color:var(--text);border-color:var(--glass-border-hover)}

@media (min-width:861px){
  /* Collapsing the rail is a token switch, not a per-element override: every
     layout that offsets itself by var(--sidebar-w) — the shared .topbar /
     .page, the per-page stylesheets, max-width calculations — reflows from
     this one line, so no page can fall out of step. */
  body.sidebar-collapsed{--sidebar-w:0px}
  body.sidebar-collapsed .sidebar{transform:translateX(-100%)}
  /* The toggle button floats at left:8px; give the topbar back a matching
     pad so its first element never hides under it. */
  body.sidebar-collapsed .topbar{padding-left:52px}
}

.sidebar-backdrop{
  position:fixed;inset:0;z-index:var(--z-backdrop);
  background:rgba(0,0,0,0.55);
  opacity:0;pointer-events:none;
  transition:opacity var(--dur) var(--ease);
}

/* ── Activity feed (right-hand drawer) ── */
.activity-toggle{
  position:relative;display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:var(--radius-sm);
  background:transparent;border:1px solid transparent;color:var(--text-dim);
  cursor:pointer;transition:var(--tr-ui);flex-shrink:0;
}
.activity-toggle:hover{background:var(--bg-hover);color:var(--text);border-color:var(--border)}
.activity-toggle svg{width:17px;height:17px}
.activity-badge{
  position:absolute;top:3px;right:3px;min-width:14px;height:14px;padding:0 3px;
  border-radius:var(--radius-sm);background:var(--accent);color:var(--on-accent);
  font-size:9px;font-weight:700;line-height:14px;text-align:center;
  display:none;
}
.activity-badge.show{display:block}
.activity-drawer{
  position:fixed;top:0;right:0;bottom:0;width:340px;max-width:88vw;z-index:var(--z-drawer);
  background:var(--bg2);border-left:1px solid var(--border);
  display:flex;flex-direction:column;
  transform:translateX(100%);transition:transform var(--dur) var(--ease);
  padding-top:var(--safe-t);padding-bottom:var(--safe-b);
}
.activity-drawer.open{transform:translateX(0)}
.activity-drawer-head{
  display:flex;align-items:center;gap:8px;padding:0 16px;height:var(--topbar-h);flex-shrink:0;
  border-bottom:1px solid var(--border);font-weight:650;letter-spacing:-.01em;
}
.activity-drawer-head .spacer{flex:1}
.activity-drawer-head button{
  background:transparent;border:none;color:var(--text-dim);cursor:pointer;
  font-size:16px;padding:4px 8px;border-radius:var(--radius-sm);
}
.activity-drawer-head button:hover{background:var(--bg-hover);color:var(--text)}
.activity-list{flex:1;overflow-y:auto;padding:8px 12px}
.activity-item{
  display:flex;gap:8px;padding:9px 4px;border-bottom:1px solid var(--border);font-size:12px;
}
.activity-item:last-child{border-bottom:none}
.activity-item .dot{margin-top:5px;flex-shrink:0}
.activity-item .body{flex:1;min-width:0}
.activity-item .msg{color:var(--text);line-height:1.4}
.activity-item .meta{font-size:9.5px;color:var(--text-dim2);margin-top:2px;text-transform:uppercase;letter-spacing:.3px}
.activity-empty{padding:24px 12px;text-align:center;color:var(--text-dim2);font-size:12px}
.activity-backdrop{
  position:fixed;inset:0;z-index:129;background:rgba(0,0,0,.4);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease);
}
.activity-backdrop.show{opacity:1;pointer-events:auto}
.sidebar-backdrop.show{opacity:1;pointer-events:auto}

.topbar{
  position:sticky;top:0;z-index:var(--z-topbar);
  display:flex;align-items:center;gap:var(--sp-3);
  padding:0 var(--sp-4);
  padding-top:var(--safe-t);
  height:calc(var(--topbar-h) + var(--safe-t));
  border-bottom:1px solid var(--border);
  background:var(--glass-bg);
  backdrop-filter:blur(var(--glass-blur)) saturate(1.3);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.3);
  flex-shrink:0;
  margin-left:var(--sidebar-w);
  transition:margin-left var(--dur) var(--ease),padding-left var(--dur) var(--ease);
}
.topbar .spacer{flex:1}
.topbar h1,.topbar .title{font-size:var(--fs-md);font-weight:600;letter-spacing:-.01em}

.page{
  position:relative;z-index:var(--z-page);
  flex:1;display:flex;flex-direction:column;
  min-height:0;min-width:0;
  width:100%;
  /* The rail is an offset, not extra canvas — subtract it from the cap or
     the content column runs off the right edge on a 1440 screen. */
  max-width:min(1440px, calc(100% - var(--sidebar-w)));
  margin:0 auto;
  margin-left:var(--sidebar-w);
  padding-bottom:var(--safe-b);
  transition:margin-left var(--dur) var(--ease);
}

/* ══ 4. COMPONENTS ═══════════════════════════════════════════════════════ */

.card{
  background:var(--bg-card);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--border);
  border-radius:var(--radius);
  padding:var(--sp-5);margin-bottom:var(--sp-4);
  box-shadow:var(--shadow-sm);
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.card:hover{border-color:var(--glass-border-hover);box-shadow:var(--shadow-md)}
.card h2{font-size:var(--fs-lg);margin-bottom:var(--sp-4);display:flex;align-items:center;gap:var(--sp-2)}

.info-card{
  background:var(--bg-card);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-radius:var(--radius);
  border:1px solid var(--border);
  overflow:hidden;
  transition:border-color var(--dur) var(--ease);
}
.info-card:hover{border-color:var(--glass-border-hover)}
.info-card-header{
  display:flex;align-items:center;gap:var(--sp-2);
  padding:10px var(--sp-4);
  border-bottom:1px solid var(--border);
  font-family:var(--font-mono);
  font-size:var(--fs-xs);font-weight:500;color:var(--text-dim2);
  text-transform:uppercase;letter-spacing:.10em;
}
.info-card-header .dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.info-card-header .spacer{flex:1}
.info-card-body{padding:var(--sp-3) var(--sp-4)}

/* ── Buttons. 34px desktop / 42px touch. Only .btn-primary carries heat. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:34px;padding:0 14px;
  border-radius:var(--radius-sm);
  border:1px solid var(--border);
  background:var(--surface);
  color:var(--text);
  font-family:var(--font-sans);font-size:var(--fs-base);font-weight:550;
  line-height:1;cursor:pointer;
  white-space:nowrap;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),
             box-shadow var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.btn:hover{background:var(--surface-hover);border-color:var(--glass-border-hover)}
.btn:active{transform:translateY(1px)}
.btn:disabled,.btn[disabled],.btn.disabled{opacity:var(--btn-disabled-opacity);cursor:not-allowed;transform:none}
.btn-primary{
  background:linear-gradient(170deg,var(--accent2) -30%,var(--accent) 55%,var(--accent-dark) 130%);
  border-color:rgba(var(--accent-rgb),0.55);
  color:var(--on-accent);font-weight:650;
  box-shadow:0 1px 0 rgba(255,255,255,0.20) inset,0 2px 12px rgba(var(--accent-rgb),0.20);
}
.btn-primary:hover{filter:brightness(1.07);box-shadow:0 1px 0 rgba(255,255,255,0.22) inset,0 4px 18px rgba(var(--accent-rgb),0.32)}
.btn-danger{background:rgba(242,85,90,0.10);border-color:rgba(242,85,90,0.35);color:var(--red)}
.btn-danger:hover{background:rgba(242,85,90,0.18)}
.btn-outline{background:transparent;border-color:var(--border);color:var(--text-dim)}
.btn-outline:hover{background:var(--surface-hover);color:var(--text)}
.btn-sm{min-height:28px;padding:0 10px;font-size:var(--fs-sm)}
.btn-icon{padding:0;width:34px}
.btn-warning{border-color:rgba(230,169,60,0.35);color:var(--amber)}
.btn-warning:hover{background:rgba(230,169,60,0.10);border-color:rgba(230,169,60,0.5)}

/* ── Fields */
input,select,textarea{
  background:var(--bg-input);
  border:1px solid var(--border);
  color:var(--text);
  font-family:var(--font-sans);font-size:var(--fs-base);
  border-radius:var(--radius-sm);
  padding:8px 11px;
  min-height:34px;
  max-width:100%;
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
textarea{line-height:1.55;resize:vertical}
input::placeholder,textarea::placeholder{color:var(--text-dim2)}
input:focus,select:focus,textarea:focus{
  border-color:var(--border-focus);
  box-shadow:0 0 0 3px rgba(var(--accent-rgb),0.12);
  outline:none;
}
input[type=checkbox],input[type=radio]{
  min-height:0;width:16px;height:16px;padding:0;
  accent-color:var(--accent);cursor:pointer;
}
input[type=range]{accent-color:var(--accent);min-height:0;padding:0;border:none;background:none}
select{
  appearance:none;-webkit-appearance:none;
  padding-right:28px;cursor:pointer;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2398a0ac' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat:no-repeat;
  background-position:right 9px center;
}
label{font-size:var(--fs-sm);color:var(--text-dim)}

/* ── Tables. Wrap in .table-wrap so wide tables scroll instead of the page. */
.table-wrap{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
table{border-collapse:separate;border-spacing:0;width:100%}
th{
  background:var(--bg2);color:var(--text-dim2);
  font-family:var(--font-mono);font-weight:500;
  padding:9px var(--sp-3);
  border:none;border-bottom:1px solid var(--border);
  font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.10em;
  text-align:left;white-space:nowrap;
}
td{padding:8px var(--sp-3);border:none;border-bottom:1px solid var(--border);color:var(--text);font-size:var(--fs-base)}
tr:last-child td{border-bottom:none}
tbody tr:hover td{background:var(--surface)}

/* ── Badges & chips */
.badge{
  display:inline-flex;align-items:center;gap:5px;
  border-radius:var(--radius-pill);
  padding:2px 9px;
  font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:500;
  letter-spacing:.05em;text-transform:uppercase;
  background:var(--surface);border:1px solid var(--border);color:var(--text-dim);
}

/* ── Status dot. Pulses only while live — heat means activity. */
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--text-dim2);flex-shrink:0}
.dot.ok,.dot.active,.dot.online{background:var(--green);box-shadow:0 0 8px rgba(78,201,160,0.45)}
.dot.warn{background:var(--amber)}
.dot.err,.dot.offline{background:var(--red)}
.dot.live{background:var(--accent);box-shadow:0 0 8px var(--accent-glow);animation:forge-pulse 2s var(--ease) infinite}
/* Animation-only modifier — combine with .ok/.warn/.err for a status dot
   whose colour reflects live state but should still pulse (e.g. "up and
   actively polling" vs. .live's fixed always-accent "this panel is live"). */
.dot.pulse{animation:forge-pulse 2s var(--ease) infinite}
@keyframes forge-pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ── Scrollbars (canonical, global). Single definition on purpose. */
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(150,168,190,0.18);border-radius:var(--radius-pill)}
::-webkit-scrollbar-thumb:hover{background:rgba(150,168,190,0.32)}
::-webkit-scrollbar-corner{background:transparent}

/* ── Focus. Always visible, never sacrificed to the aesthetic. */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-xs)}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:none}

/* ── Toast */
.forge-toast{
  position:fixed;left:50%;z-index:var(--z-toast);
  bottom:calc(20px + var(--safe-b));
  transform:translateX(-50%) translateY(8px);
  max-width:min(92vw,420px);
  padding:10px 16px;border-radius:var(--radius-sm);
  font-size:var(--fs-base);font-weight:500;
  background:var(--bg3);border:1px solid var(--border);color:var(--text);
  box-shadow:var(--shadow-lg);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease);
  opacity:0;pointer-events:none;
}
.forge-toast.show{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}
.toast-error{border-color:rgba(242,85,90,0.45);color:var(--red)}

/* ── Settings gear */
.forge-gear-btn{
  background:none;border:1px solid var(--border);color:var(--text-dim);
  width:32px;height:32px;border-radius:var(--radius-sm);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:var(--tr-ui);flex-shrink:0;
}
.forge-gear-btn:hover{background:var(--surface-hover);color:var(--accent);border-color:var(--glass-border-hover)}

/* ── Modal */
.forge-modal-overlay{
  position:fixed;inset:0;z-index:var(--z-modal);
  background:rgba(0,0,0,0.66);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;
  padding:var(--sp-4);
  animation:fadeIn var(--dur-fast) var(--ease);
}
.forge-modal{
  background:var(--bg2);
  border:1px solid var(--border);
  border-radius:var(--radius);
  width:100%;max-width:540px;max-height:min(84vh,720px);
  box-shadow:var(--shadow-lg);
  display:flex;flex-direction:column;
  animation:modalSlideUp var(--dur) var(--ease);
}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes modalSlideUp{from{opacity:0;transform:translateY(12px) scale(.985)}to{opacity:1;transform:none}}

.forge-modal-header{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--border);
}
.forge-modal-header h3{margin:0;font-size:var(--fs-lg)}
.forge-modal-close{
  background:none;border:none;color:var(--text-dim);font-size:22px;
  cursor:pointer;width:32px;height:32px;border-radius:var(--radius-sm);line-height:1;
  display:flex;align-items:center;justify-content:center;
}
.forge-modal-close:hover{background:var(--surface-hover);color:var(--text)}

.forge-modal-tabs{display:flex;gap:2px;padding:0 var(--sp-5);border-bottom:1px solid var(--border);overflow-x:auto;scrollbar-width:none}
.forge-modal-tabs::-webkit-scrollbar{display:none}
.fmtab{
  background:none;border:none;color:var(--text-dim);
  padding:11px var(--sp-3);min-height:var(--tab-h);
  font-family:var(--font-sans);font-size:var(--fs-base);font-weight:550;
  cursor:pointer;white-space:nowrap;
  border-bottom:2px solid transparent;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease);
}
.fmtab:hover{color:var(--text)}
.fmtab.active{color:var(--text-bright);border-bottom-color:var(--accent)}

.forge-modal-body{padding:var(--sp-4) var(--sp-5) var(--sp-5);overflow-y:auto;flex:1}
.fmtab-panel{display:none}
.fmtab-panel.active{display:block}

.forge-section-label{margin-bottom:10px;display:block}
.forge-row{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}

/* ── Theme picker */
.forge-theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(94px,1fr));gap:var(--sp-2)}
.forge-theme-card{cursor:pointer;border-radius:var(--radius-sm);padding:7px;border:1px solid transparent;transition:var(--tr-ui)}
.forge-theme-card:hover{background:var(--surface-hover)}
.forge-theme-card.active{border-color:var(--accent);background:var(--surface)}

.forge-theme-name{font-size:var(--fs-sm);text-align:center;color:var(--text-dim);font-weight:500}

/* ── Patch notes */
.forge-patch{margin-bottom:var(--sp-4)}
.forge-patch-header{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:6px}
.forge-patch-ver{
  background:linear-gradient(135deg,var(--accent2),var(--accent));
  color:var(--on-accent);padding:2px 9px;border-radius:var(--radius-pill);
  font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;
}
.forge-patch-date{color:var(--text-dim2);font-size:var(--fs-sm);font-family:var(--font-mono)}
.forge-patch ul{margin:0;padding-left:18px;font-size:var(--fs-base);color:var(--text-dim)}
.forge-patch li{margin-bottom:4px}

/* ══ 5. COMMAND PALETTE ══════════════════════════════════════════════════ */

.forge-cmdk{
  position:fixed;inset:0;z-index:var(--z-toast);
  background:rgba(0,0,0,0.62);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:flex;align-items:flex-start;justify-content:center;
  padding:12vh var(--sp-4) var(--sp-4);
  animation:fadeIn var(--dur-fast) var(--ease);
}
.forge-cmdk[hidden]{display:none}
.forge-cmdk-box{
  width:100%;max-width:520px;
  background:var(--bg2);border:1px solid var(--glass-border-hover);
  border-radius:var(--radius);box-shadow:var(--shadow-lg);
  overflow:hidden;display:flex;flex-direction:column;
  animation:modalSlideUp var(--dur) var(--ease);
}
.forge-cmdk-input{
  width:100%;border:none;background:none;border-radius:0;
  border-bottom:1px solid var(--border);
  padding:14px var(--sp-4);font-size:var(--fs-lg);min-height:52px;
}
.forge-cmdk-input:focus{box-shadow:none;border-color:var(--border)}
.forge-cmdk-list{list-style:none;margin:0;padding:6px;overflow-y:auto;max-height:min(50vh,340px)}
.forge-cmdk-list li{
  display:flex;align-items:center;gap:10px;
  padding:0 12px;min-height:38px;border-radius:var(--radius-sm);
  font-size:var(--fs-base);color:var(--text-dim);cursor:pointer;
}
.forge-cmdk-list li .nav-icon{width:15px;height:15px;flex-shrink:0}
.forge-cmdk-list li[aria-selected=true]{background:var(--surface-hover);color:var(--text-bright)}
.forge-cmdk-list li[aria-selected=true] .nav-icon{color:var(--accent)}
.forge-cmdk-empty{padding:20px;text-align:center;color:var(--text-dim2);font-size:var(--fs-base)}
.forge-cmdk-foot{
  display:flex;gap:var(--sp-4);align-items:center;
  padding:8px var(--sp-4);border-top:1px solid var(--border);
  font-size:var(--fs-xs);color:var(--text-dim2);
}

/* ══ 6. MOBILE NAV ═══════════════════════════════════════════════════════ */

/* left: hamburger · center: hold-to-change icons · right: settings */
/* The always-on bottom bar needs content clearance on every screen */
html.forge-app-shell body{padding-bottom:calc(var(--mobile-nav-h) + var(--safe-b))}
.mn-center a.active{color:var(--text)}

/* ══ 7. BACKGROUND ═══════════════════════════════════════════════════════
   The plate has a faint machined grid. Deliberately near-invisible: it gives
   the dark field a surface without competing with content. */

.bg-grid{
  position:fixed;inset:0;z-index:var(--z-bg);pointer-events:none;overflow:hidden;
  background:
    linear-gradient(rgba(150,168,190,.045) 1px,transparent 1px),
    linear-gradient(90deg,rgba(150,168,190,.045) 1px,transparent 1px);
  background-size:64px 64px;
  mask-image:radial-gradient(ellipse 70% 60% at 50% 25%,#000 10%,transparent 72%);
  -webkit-mask-image:radial-gradient(ellipse 70% 60% at 50% 25%,#000 10%,transparent 72%);
}
.bg-grid::before{content:none}
.bg-orb{
  position:fixed;z-index:var(--z-bg);pointer-events:none;
  width:820px;height:820px;border-radius:50%;
  top:-22%;left:50%;transform:translateX(-50%);
  background:radial-gradient(circle,rgba(var(--accent-rgb),.055) 0%,rgba(var(--accent2-rgb),.022) 34%,transparent 66%);
}
.bg-particles{display:none}

/* ══ 8. AUDIO PANEL ══════════════════════════════════════════════════════ */

.audio-mode.system-wide{color:var(--green);background:rgba(78,201,160,.10)}
.audio-mode.focused{color:var(--accent);background:rgba(var(--accent-rgb),.10)}

.audio-row .dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.audio-row .dot.active{background:var(--green);box-shadow:0 0 8px rgba(78,201,160,.45)}
.audio-row .dot.muted{background:var(--text-dim2)}
.audio-row .info{flex:1;min-width:0}
.audio-row .app-name{font-weight:600;color:var(--text);font-size:var(--fs-base)}

.audio-row .audio-focus-btn.focused{color:var(--accent);border-color:rgba(var(--accent-rgb),.30)}

.audio-focused-info .label{font-size:var(--fs-xs)}
.audio-focused-info .value{font-size:var(--fs-base);font-weight:600;color:var(--accent)}
.audio-focused-info .spacer{flex:1}

/* ══ 9. UTILITIES ════════════════════════════════════════════════════════ */

.spacer{flex:1}
.muted{color:var(--text-dim)}
.dim{color:var(--text-dim2)}
.hot{color:var(--accent)}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}

.skeleton{
  background:linear-gradient(90deg,var(--surface) 25%,var(--surface-hover) 37%,var(--surface) 63%);
  background-size:400% 100%;
  animation:skeleton 1.4s ease infinite;
  border-radius:var(--radius-xs);color:transparent!important;
}
@keyframes skeleton{from{background-position:100% 0}to{background-position:-100% 0}}

/* ══ 10. RESPONSIVE ══════════════════════════════════════════════════════
   Breakpoint is 860px: below it, the rail becomes a drawer and the five
   primary destinations move to a thumb-reachable bottom bar. Tuned for the
   Android WebView wrapper, which is the main mobile surface. */

@media (max-width:1100px){
  :root{--sidebar-w:200px}
  /* Keep the rail's standing width in step with the offset token above. */
  .sidebar{width:200px}
}
@media (max-width:860px){
  /* Zeroing the token collapses every layout that offsets itself by the rail,
     including the per-page stylesheets, without editing each one. */
  :root{--sidebar-w:0px}

  .sidebar{transform:translateX(-100%);width:min(280px,82vw);box-shadow:var(--shadow-lg)}
  .sidebar.open{transform:translateX(0)}
  .topbar{margin-left:0;padding-left:52px}
  .page{margin-left:0;max-width:100%}
  /* The heat line / toast used to sit above the mobile bottom nav, but that
     nav was removed (no .forge-mobilenav is generated any more), leaving the
     line floating 56px up the screen with nothing beneath it. Pin both to the
     real bottom edge (above the gesture bar via --safe-b). */
  body::after{bottom:var(--safe-b)}
  .forge-toast{bottom:calc(var(--safe-b) + 12px)}

  /* Touch targets: 42px minimum for anything you tap. */
  .btn,button,select,input[type=text],input[type=password],input[type=number],
  input[type=search],input[type=email],input[type=url]{min-height:42px}
  .btn-sm{min-height:40px}
  .sidebar-nav a{min-height:44px;font-size:var(--fs-md)}
  .fmtab{min-height:44px}
  .forge-gear-btn,.btn-icon{width:40px;min-height:40px}
  /* Icon-only .btn-sm (gallery toolbar) stay square so the tap area isn't a sliver */
  .btn-sm:has(> svg:only-child){min-width:40px;padding:0}
  /* ForgeGen gallery tabs + size presets + tag chips get thumb-sized targets */
  .gallery-tab{display:inline-flex;align-items:center;min-height:40px;padding:0 12px}
  .thumb-preset{display:inline-flex;align-items:center;min-height:40px;padding:0 12px;font-size:11px}
  .tags-btn{display:inline-flex;align-items:center;min-height:40px;padding:0 12px;font-size:11px;line-height:1}
  .sidebar-toggle,.activity-toggle{width:44px;height:44px}
  #info-btn{width:44px;height:44px;font-size:18px;display:inline-flex;align-items:center;justify-content:center}
  .sidebar-bottom .rocket-link,.topbar .rocket-link{min-height:40px}
  .activity-drawer-head button{min-width:44px;min-height:44px}

  /* Text inputs below 16px make the WebView zoom on focus. */
  input,textarea,select{font-size:16px}

  .card,.info-card{border-radius:var(--radius-sm)}
  .card{padding:var(--sp-4)}
  .forge-modal{max-width:100%;max-height:88vh}
  .forge-modal-header,.forge-modal-tabs,.forge-modal-body{padding-left:var(--sp-4);padding-right:var(--sp-4)}

  /* Wide tables scroll inside themselves rather than the page. */
  table{display:block;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}

  h1{font-size:var(--fs-xl)}
  h2{font-size:var(--fs-lg)}

  /* Two- and three-column grids collapse. Covers the common inline patterns
     across the page-level stylesheets without editing each one. */
  .grid-2,.grid-3,.grid-4,.stats-grid,.metrics-grid,.two-col,.three-col{
    grid-template-columns:1fr!important;
  }

  .forge-cmdk{padding-top:8vh}
}
@media (max-width:420px){
  :root{--sp-5:16px}
  .forge-theme-grid{grid-template-columns:repeat(2,1fr)}
}

/* Pointer-coarse devices get generous targets regardless of viewport width. */
@media (pointer:coarse){
  .sidebar-nav a{min-height:42px}
  a,button,[role=button]{-webkit-tap-highlight-color:rgba(var(--accent-rgb),0.12)}
  /* Hover-only affordances need a non-hover fallback on touch: the LoRA
     delete ✕ is otherwise stuck at 40% opacity (no hover to reveal it). */
  .lora-delete-btn{opacity:.75!important}

  /* Gallery item delete/fav are display:none until :hover — there is no hover on
     a touchscreen, so they'd be unreachable (favoriting was effectively impossible
     from the grid). Show them always and enlarge from 20px to a tappable 36px.
     Thumbnails are ~185px wide on phones, so 36px is proportionate. */
  .history-item .delete-btn,
  .history-item .fav-btn{display:flex;width:36px;height:36px;font-size:18px;top:6px}
  .history-item .delete-btn{right:6px}
  .history-item .fav-btn{left:6px}
  /* In multi-select the checkbox occupies the top-left slot; don't double-stack. */
  #result-area.sel-mode .fav-btn{display:none}

  /* Dim hover-to-brighten close/delete affordances get a legible touch fallback. */
  .model-list-close{opacity:1}
  .load-popover .lp-item .del{opacity:1}
}

/* ══ 11. MOTION & PRINT ══════════════════════════════════════════════════ */

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;
    animation-iteration-count:1!important;
    transition-duration:.01ms!important;
    scroll-behavior:auto!important;
  }
  .dot.live{animation:none}
}

@media print{
  .sidebar,.sidebar-toggle,.sidebar-backdrop,.forge-mobilenav,.topbar,
  .bg-grid,.bg-orb,#bg-canvas,.forge-gear-btn,.forge-toast{display:none!important}
  body{background:#fff;color:#000}
  .page{margin:0;max-width:100%}
  .card,.info-card{border:1px solid #ccc;background:none;box-shadow:none}
}

/* ══ 6b. BOTTOM BAR SLOT PICKER — hold an icon to remap it ═══════════════ */

@media (max-width:480px){
}

/* ── Background library items ── */
.bg-lib-item{
  background:var(--bg3);border:1px solid var(--border);border-radius:var(--radius-sm);
  cursor:pointer;overflow:hidden;transition: color .12s, background-color .12s, border-color .12s, box-shadow .12s, opacity .12s, transform .12s, filter .12s, fill .12s, stroke .12s;
}
.bg-lib-item:hover{border-color:var(--accent);transform:translateY(-1px)}
.bg-lib-item img{display:block}

/* ══ 7. PAGE TRANSITIONS, FOCUS RINGS, EMPTY STATES ═══════════════════════ */

/* 7a. Smooth page transitions — fade in on load, fade out before nav */
body{animation:forgeFadeIn .18s ease both}
@keyframes forgeFadeIn{from{opacity:0}to{opacity:1}}
body.forge-leaving{opacity:0;transition:opacity .14s ease}

/* 7b. Card-like tiles lift on keyboard focus. The base focus ring lives in
       the foundation (section 4); these only add the hover parallax. */
.vid-card:focus-visible,.widget:focus-visible,.home-card:focus-visible,.tool-card:focus-visible,
.store-card:focus-visible,.sub-chip:focus-visible,.bg-lib-item:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;transform:translateY(-1px)
}

/* 7c. Smooth theme swaps — enabled briefly while a theme changes */
html.theme-anim *,html.theme-anim *::before,html.theme-anim *::after{
  transition:background-color .35s ease,color .35s ease,border-color .35s ease,
             box-shadow .35s ease,fill .35s ease !important;
}

/* 7d. Shared empty-state block — icon, message, optional action */
.forge-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;padding:34px 16px;text-align:center;
}
.forge-empty .fe-icon{
  width:44px;height:44px;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;font-size:20px;
}
.forge-empty .fe-title{font-size:13px;font-weight:700;color:var(--text)}
.forge-empty .fe-hint{font-size:11px;color:var(--text-dim2);max-width:360px;line-height:1.5}
.forge-empty .fe-action{
  margin-top:4px;background:var(--accent);border:none;border-radius:var(--radius-sm);
  color:var(--on-accent);font-size:11px;font-weight:700;padding:9px 20px;cursor:pointer;
}
.forge-empty .fe-action:hover{filter:brightness(1.1)}
.forge-empty .fe-action.ghost{background:var(--bg3);color:var(--text);border:1px solid var(--border)}

/* 7e. Live theme preview mini-UI */
.forge-theme-preview{
  height:54px;border-radius:var(--radius-xs);border:1px solid var(--border);
  padding:5px;margin-bottom:6px;position:relative;overflow:hidden;
}
.tp-card{
  height:100%;border-radius:var(--radius-xs);border:1px solid;
  display:flex;flex-direction:column;padding:4px 5px;gap:3px;
}
.tp-bar{height:5px;border-radius:var(--radius-xs);margin-bottom:2px}
.tp-lines{display:flex;flex-direction:column;gap:2px}
.tp-lines i{height:2px;border-radius:var(--radius-xs);width:70%}
.tp-lines i:nth-child(2){width:50%}
.tp-lines i:nth-child(3){width:60%;opacity:.6}
.tp-btn{width:34px;height:8px;border-radius:var(--radius-xs);margin-top:auto}
.tp-dots{position:absolute;right:8px;bottom:8px;display:flex;gap:3px}
.tp-dots b{width:6px;height:6px;border-radius:50%}

/* ══ 8. AMBIENCE — glow, grain, vignette, ambiance tints, skeletons ═══════ */

/* 8a. Ambient cursor glow — follows the pointer, never blocks clicks */
#forge-cursor-glow{
  position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:0;
  pointer-events:none;opacity:.22;will-change:background;
  background:radial-gradient(560px circle at 0 0, var(--accent-glow), transparent 60%);
}
html.forge-no-glow #forge-cursor-glow{display:none}

/* 8b. Film grain + vignette — one fixed layer above everything */
#forge-grain{
  position:fixed;inset:0;z-index:300;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}
#forge-vignette{
  position:fixed;inset:0;z-index:299;pointer-events:none;
  background:radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,.28) 100%);
}
html.forge-no-grain #forge-grain,html.forge-no-grain #forge-vignette{display:none}
/* A black vignette reads as dirt on a light plate — kill it there. */
html[data-forge-theme="light"] #forge-vignette,
html[data-forge-theme="frutigeraero"] #forge-vignette,
html[data-forge-theme="wii"] #forge-vignette{display:none}

/* 8c. Per-page ambiance tints (set via data-ambiance on body) */
body[data-ambiance="movies"]::before,body[data-ambiance="gen"]::before,
body[data-ambiance="finance"]::before,body[data-ambiance="tinker"]::before,
body[data-ambiance="dash"]::before{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
}
body[data-ambiance="movies"]::before{background:radial-gradient(900px 500px at 80% -10%, rgba(244,114,182,.10), transparent 60%)}
body[data-ambiance="gen"]::before{background:radial-gradient(900px 500px at 20% -10%, rgba(var(--cyan-rgb),.08), transparent 60%)}
body[data-ambiance="finance"]::before{background:radial-gradient(900px 500px at 80% 110%, rgba(78,201,160,.08), transparent 60%)}
body[data-ambiance="tinker"]::before{background:radial-gradient(900px 500px at 50% -10%, rgba(168,139,255,.08), transparent 60%)}
body[data-ambiance="dash"]::before{background:radial-gradient(900px 500px at 15% 110%, rgba(var(--accent-rgb),.07), transparent 60%)}

/* 8d. Skeleton loaders */
.skel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}
.skel-card{
  background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);
  padding:0 0 10px;overflow:hidden;
}
.skel-card .sk-thumb{aspect-ratio:16/9;background:linear-gradient(100deg,var(--shimmer-lo) 40%,var(--shimmer-hi) 50%,var(--shimmer-lo) 60%);background-size:200% 100%;animation:skelShimmer 1.3s linear infinite}
.skel-card .sk-line{height:9px;border-radius:var(--radius-xs);margin:8px 10px 0;background:linear-gradient(100deg,var(--shimmer-lo) 40%,var(--shimmer-hi) 50%,var(--shimmer-lo) 60%);background-size:200% 100%;animation:skelShimmer 1.3s linear infinite}
.skel-card .sk-line.short{width:55%}
@keyframes skelShimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* 8e. Sliding active pill in the bottom bar */

.forge-mobilenav ul li a.active{color:var(--accent)}

/* 8f. Typography — display font for headings. --font-display resolves to the
       sans stack (no webfont is shipped); headings and instrument labels just
       inherit it, so no per-selector font-family overrides are needed here. */
.stat .value{font-variant-numeric:tabular-nums}

/* 8g. Reduced motion — both media query and the manual toggle */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
  #forge-cursor-glow{display:none !important}
}

html.forge-reduced-motion *,html.forge-reduced-motion *::before,html.forge-reduced-motion *::after{
  animation-duration:.01ms !important;transition-duration:.01ms !important;
}
html.forge-reduced-motion #forge-cursor-glow{display:none !important}

/* ── Settings: Download Update button ── */
.forge-update-btn{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--green);color:var(--on-accent);text-decoration:none;
  font-size:11px;font-weight:700;padding:8px 16px;border-radius:var(--radius-sm);
  box-shadow:0 0 0 2px rgba(78,201,160,.25);
}
.forge-update-btn:hover{filter:brightness(1.1)}

/* ══ 9. MOBILE APP REDESIGN — scoped to the Forge Android shell ════════════
   Everything here applies ONLY inside the app (html.forge-app-shell):
   thumb-friendly touch targets, bigger readable type, generous spacing.
   The regular webpage is untouched. */

/* 9a. Typography — larger, more readable on a phone */
html.forge-app-shell{--fs-base:14px}
html.forge-app-shell body{font-size:14px;line-height:1.55;letter-spacing:.1px}
html.forge-app-shell h1{font-size:24px}
html.forge-app-shell h2{font-size:20px}
html.forge-app-shell h3{font-size:17px}
html.forge-app-shell .widget-head,
html.forge-app-shell .bc-title,
html.forge-app-shell .sec-title,
html.forge-app-shell .section-title,
html.forge-app-shell .vid-section-title,
html.forge-app-shell .forge-section-label{font-size:12px}
html.forge-app-shell .vid-title{font-size:14px}
html.forge-app-shell .vid-meta{font-size:11px}
html.forge-app-shell .stat .value{font-size:22px}

/* 9b. Touch targets — every control is thumb-sized */
html.forge-app-shell button,html.forge-app-shell .btn,html.forge-app-shell .mini-btn,
html.forge-app-shell a[href]{min-height:44px}
html.forge-app-shell input,html.forge-app-shell textarea,html.forge-app-shell select{min-height:46px;font-size:15px}
html.forge-app-shell .hero-btn,html.forge-app-shell .sp-tab,html.forge-app-shell .edit-btn{padding:10px 16px;font-size:12px}
html.forge-app-shell .vid-actions .mini-btn{padding:10px 0}

/* 9c. Page rhythm — generous air on a small screen */
html.forge-app-shell .page{padding:14px 14px 24px}
html.forge-app-shell .big-card{padding:16px 16px 18px;border-radius:var(--radius-lg);margin-bottom:18px}
html.forge-app-shell .widget-body{padding:8px 16px 16px}
html.forge-app-shell .widget-head{padding:14px 16px 6px}

/* 9d. Dashboard cards — bigger, easier to read */
html.forge-app-shell .widget{--card-radius:18px}
html.forge-app-shell .email-row,html.forge-app-shell .anomaly-row{padding:9px 0;font-size:13px}
html.forge-app-shell .email-subj,html.forge-app-shell .anomaly-summary{font-size:13px}
html.forge-app-shell .email-meta,html.forge-app-shell .anomaly-meta{font-size:11px}
html.forge-app-shell .size-btn{font-size:10px;padding:6px 8px}
html.forge-app-shell .briefing-text{font-size:14px}
html.forge-app-shell .todo-item,html.forge-app-shell .link-item{font-size:14px}

/* 9e. Forge Gen — thumb-friendly controls */
html.forge-app-shell #natural-prompt,html.forge-app-shell #negative-prompt{min-height:96px;font-size:15px}
html.forge-app-shell .workflow-btns .wf-btn{padding:10px 14px;font-size:12px}
html.forge-app-shell .gen-btn{padding:16px;font-size:15px;border-radius:var(--radius)}
html.forge-app-shell .lora-chips .chip,html.forge-app-shell .tag-chip{padding:9px 14px;font-size:12px}

/* 9f. Movies — roomier cards and controls */
html.forge-app-shell .vid-grid{gap:14px}
html.forge-app-shell .vid-card{border-radius:var(--radius-lg)}
html.forge-app-shell .vid-info{padding:10px 12px 12px}
html.forge-app-shell .connect-btn,.forge-app-shell .stremio-btn{padding:14px 18px;font-size:13px}
html.forge-app-shell .pl-row{padding:12px 14px;border-radius:var(--radius)}
html.forge-app-shell .pl-row img{width:52px;height:52px}

/* 9g. App topbar — taller with inset, readable title */
html.forge-app-shell .topbar{
  height:calc(52px + var(--safe-t));
  padding-top:calc(var(--safe-t) + 4px);
}
html.forge-app-shell .topbar h1,html.forge-app-shell .topbar .title{font-size:16px}

/* 9h. Drawer — bottom-sheet feel on the phone */
@media (max-width:860px){
  html.forge-app-shell .sidebar{width:min(320px,86vw);border-radius:0 var(--radius-lg) var(--radius-lg) 0}
  html.forge-app-shell .sidebar-nav a{padding:14px 16px;font-size:14px}
  html.forge-app-shell .sidebar-nav a svg{width:22px;height:22px}
  html.forge-app-shell .nav-group{font-size:11px;padding:10px 16px 6px}
  html.forge-app-shell .sidebar-brand{padding:18px 16px 12px}

  /* Bottom bar — bigger icons, more air */
  html.forge-app-shell .mn-center a svg{width:24px;height:24px}
  html.forge-app-shell .mn-center a{font-size:10px;gap:3px}
  html.forge-app-shell .mn-hamburger,html.forge-app-shell .mn-settings{width:58px}
  html.forge-app-shell .mn-hamburger svg,html.forge-app-shell .mn-settings svg{width:24px;height:24px}
  html.forge-app-shell .mn-hold-hint svg{width:20px;height:20px}
  html.forge-app-shell .mn-center ul{padding-left:28px}
}

/* ══ SHARED COMPONENTS ═════════════════════════════════════════════════════
   Promoted out of the GEN PAGE STYLES block. These are the app's shared
   component library — buttons, form fields, cards, overlays and utilities
   that are used by pages beyond /gen, so they stay unscoped.
   ══════════════════════════════════════════════════════════════════════════ */

@keyframes forge-ambient-drift {
  from { background-position: 0% 0%, 100% 100%, 50% 50%; }
  to   { background-position: 30% 20%, 70% 80%, 45% 55%; }
}/* ── Glass Card (2026) ── */ .glass-card{
  background:var(--bg-card);
  border:1px solid var(--glass-border);
  border-radius:var(--radius);
  padding:12px;
  backdrop-filter: blur(28px) saturate(1.5);
  -webkit-backdrop-filter: blur(28px) saturate(1.5);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.2s, border-color 0.2s;
} .glass-card:hover{
  box-shadow: 0 4px 16px rgba(244,114,182,0.06), 0 0 0 1px rgba(244,114,182,0.08);
  border-color: rgba(244,114,182,0.15);
} .card-header{
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
} .card-header h3{
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  opacity: 0.7;
}   .collapse-text{ pointer-events: none; } .card-body{ transition: max-height 0.2s ease; overflow: hidden; } .card-body.collapsed{ display: none; }/* ── Info Row ── */ .info-row{ display: flex; align-items: center; gap: 6px; margin-bottom: 4px; } .info-row label{ font-size: 10px; color: var(--text-dim); min-width: 60px; } .info-row .value{ font-size: 10px; color: var(--text); }/* ── Field Group ── */ .field-group{ margin-bottom: 6px; position: relative; } .field-group label{ display: block; font-size: 10px; color: var(--text-dim); margin-bottom: 2px; }/* ── Tags Button & Wallet Panel ── */ .tags-btn{
  font-size:10px;
  padding:1px 8px;
  border-radius:var(--radius-xs);
  background:var(--bg-card);
  border:1px solid var(--glass-border);
  color:var(--text-dim);
  cursor:pointer;
  line-height:18px;
  transition:color .15s, border-color .15s;
} .tags-btn:hover{
  color:var(--text);
  border-color:var(--accent);
  background:rgba(var(--accent-rgb),.08);
} .tags-btn:active{ opacity:.7; } .tags-panel{
  margin-top:4px;
  border:1px solid var(--glass-border);
  border-radius:var(--radius-sm);
  background:var(--bg-card);
  overflow:hidden;
  box-shadow:0 4px 16px rgba(0,0,0,.35);
} .tags-header{
  display:flex;align-items:center;justify-content:space-between;
  padding:6px 10px;
  font-size:10px;
  color:var(--text-dim);
  border-bottom:1px solid var(--glass-border);
  background:var(--surface);
} .tags-total{ color:var(--text-dim); font-size:9px; } .tags-tabs{
  display:flex;
  border-bottom:1px solid var(--glass-border);
  background:var(--surface);
} .tags-tab{
  flex:1;
  font-size:9px;
  padding:4px 6px;
  border:none;
  background:transparent;
  color:var(--text-dim);
  cursor:pointer;
  border-bottom:2px solid transparent;
  transition:color .15s, border-color .15s;
} .tags-tab:hover{ color:var(--text); } .tags-tab.active{
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
  text-shadow: 0 0 6px rgba(var(--accent-rgb),0.3);
} .tags-body{
  max-height:200px;
  overflow-y:auto;
  padding:6px 8px;
  display:flex;
  flex-wrap:wrap;
  gap:4px;
  align-content:flex-start;
} .tags-body .tags-empty{
  width:100%;
  text-align:center;
  color:var(--text-dim);
  font-size:9px;
  padding:10px 0;
} .tags-body .tag-chip{
  display:inline-flex;
  align-items:center;
  gap:3px;
  font-size:9px;
  padding:2px 7px;
  border-radius:var(--radius);
  background:var(--surface);
  border:1px solid var(--glass-border);
  color:var(--text);
  cursor:pointer;
  transition: color .12s, background-color .12s, border-color .12s, box-shadow .12s, opacity .12s, transform .12s, filter .12s, fill .12s, stroke .12s;
  user-select:none;
  white-space:nowrap;
} .tags-body .tag-chip:hover{
  border-color:var(--accent);
  background:rgba(var(--accent-rgb),.1);
  color:var(--accent);
} .tags-body .tag-chip.tag-used{
  opacity:.4;
  text-decoration:line-through;
} .tags-body .tag-chip .tag-src{
  font-size:7px;
  color:var(--text-dim);
  opacity:.6;
}/* Model tags - cyan tint */ .tags-body .tag-chip.tag-chip-model{
  border-color:rgba(var(--cyan-rgb),.4);
  background:rgba(var(--cyan-rgb),.08);
} .tags-body .tag-chip.tag-chip-model:hover{
  border-color:var(--cyan);
  background:rgba(var(--cyan-rgb),.18);
  color:var(--cyan);
}/* LoRA tags - green tint, wins over cyan when both apply */ .tags-body .tag-chip.tag-chip-lora{
  border-color:rgba(78,201,160,.4);
  background:rgba(78,201,160,.08);
} .tags-body .tag-chip.tag-chip-lora:hover{
  border-color:var(--green);
  background:rgba(78,201,160,.18);
  color:var(--green);
} .tags-footer{
  padding:4px 8px;
  border-top:1px solid var(--glass-border);
  display:flex;
  justify-content:flex-end;
} .tags-close-btn{
  font-size:9px;
  padding:2px 10px;
  border-radius:var(--radius-xs);
  background:transparent;
  border:1px solid var(--glass-border);
  color:var(--text-dim);
  cursor:pointer;
} .tags-close-btn:hover{ color:var(--text); border-color:var(--text-dim); }/* ── Slider Group ── */ .slider-group{
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
} .slider-group input[type="range"]{
  flex: 1;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: var(--glass-border);
  border-radius:var(--radius-xs);
  outline: none;
} .slider-group input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance: none;
  width: 12px; height: 12px;
  border-radius:50%;
  background: var(--accent);
  cursor: pointer;
  box-shadow: 0 0 10px rgba(var(--accent-rgb),0.4);
} .slider-group input[type="range"]::-moz-range-thumb{
  width: 12px; height: 12px;
  border-radius:50%;
  background: var(--accent);
  cursor: pointer;
  border: none;
  box-shadow: 0 0 10px rgba(var(--accent-rgb),0.4);
}
.progress-bar{ height: 6px; background: var(--glass-border); border-radius:var(--radius-xs); overflow: hidden; } .progress-fill{ height: 100%; background: linear-gradient(90deg, var(--accent-dark), var(--accent)); border-radius:var(--radius-xs); transition: width 0.3s; width: 0%; } .progress-fill.active{ background: linear-gradient(90deg, var(--accent), var(--accent2), var(--accent-dark), var(--accent)); background-size: 300% 100%; animation: neonShift 2s linear infinite; } .progress-fill.loading{ background: linear-gradient(90deg, var(--amber), var(--orange)); animation: pulse-load 1.2s ease-in-out infinite; background-size: 200% 100%; } .progress-text{ font-size: 9px; color: var(--text-dim); margin-top: 2px; }/* ── Gallery ── */ .gallery-tabs{ display: flex; gap: 2px; margin-bottom: 6px; background: var(--surface); border-radius:var(--radius-sm); padding: 2px; } .gallery-tab{ padding: 4px 10px; font-size: 10px; border: none; border-radius:var(--radius-sm); background: transparent; color: var(--text-dim); cursor: pointer; font-family: var(--font-sans); transition: color 0.15s, background-color 0.15s, border-color 0.15s, box-shadow 0.15s, opacity 0.15s, transform 0.15s, filter 0.15s, fill 0.15s, stroke 0.15s; } .gallery-tab:hover{ color: var(--text); background: var(--surface-hover); } .gallery-tab.active{ color: var(--text); background: var(--surface-active); box-shadow: 0 1px 3px rgba(0,0,0,0.2); } .gallery-tab:focus-visible{ outline: 2px solid var(--accent); outline-offset: 1px; } .gallery-toolbar{ display: flex; flex-wrap: wrap; gap: 3px; margin: 6px 0; }/* Gallery header carries a lot of icon buttons; on narrow screens they wrap
   to two rows while the title stays vertically centred between them. Stack
   the title above the button group instead. */ @media (max-width:860px){
  #gallery-card > .card-header { flex-wrap: wrap; align-items: flex-start; row-gap: 4px; }
  #gallery-card > .card-header > .gap-row { flex: 1 1 100%; flex-wrap: wrap; justify-content: flex-start; }
}
/* ── Skeleton Loading ── */ @keyframes skeleton-shimmer{ 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } .skeleton-card{ border-radius:var(--radius-sm); aspect-ratio: 1; background: linear-gradient(90deg, var(--shimmer-lo) 25%, var(--shimmer-hi) 50%, var(--shimmer-lo) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s ease-in-out infinite; border: 1px solid var(--glass-border); }/* ── Mobile Responsive ── */ @media (max-width: 768px){
  /* Column stacking */
  #gen-layout-row { flex-direction: column; }
  #gen-left-col { order: -1; max-height: none; width: 100%; min-width: 0; border-right: none; border-bottom: 1px solid var(--glass-border); }
  #gen-right-col { width: 100%; min-width: 0; }
  #gen-layout { padding: 4px; padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
  #gen-layout-row { gap: 4px; }

  /* Generate button row — a single shared height so the primary button and
     the square icon buttons line up instead of stepping 48/44/40px. */
  #gen-action-row { flex-direction: column; gap: 6px; }
  #gen-action-row button { width: 100%; min-height: 48px; font-size: 14px; }
  /* !important: the global mobile `.gap-row{flex-wrap:wrap!important}` below
     otherwise forces the icon buttons onto a second, left-hanging line. */
  #generate-btn-card .gap-row { flex-wrap: nowrap !important; gap: 6px; align-items: stretch; }
  #generate-btn-card .gap-row .btn { min-height: 48px; height: 48px; font-size: 14px; }
  #generate-btn-card .gap-row .btn-primary { flex: 1 1 auto; min-width: 0; }
  #generate-btn-card .gap-row .btn-sm { flex: 0 0 48px; width: 48px; min-width: 48px; padding: 0; }
  #generate-btn { width: 100%; }
  #wf-generate-btn { width: 100%; }
  #anim-gen-btn { width: 100%; }

  /* LoRA / Queue wallet — restore real tap targets on the controls whose
     `all: unset` reset had erased the global touch sizing. */
  body#gen-body .lora-wallet .wallet-btn { min-width: 44px; min-height: 44px; font-size: 16px; }
  body#gen-body .lora-wallet .wallet-close-btn { min-height: 44px; padding: 0 18px; font-size: 12px; }
  body#gen-body .lora-wallet input[type="text"] { min-height: 44px; }

  /* Prompt tools (Expand / LoRAs / Tags) — equal columns, one row. */
  body#gen-body .prompt-tools-row { display: flex; gap: 6px; margin: 4px 0 6px; }
  body#gen-body .prompt-tool-btn {
    flex: 1 1 0; min-width: 0; min-height: 44px;
    justify-content: center; text-align: center;
    padding: 0 6px; font-size: 11px;
  }

  /* Results — compact 2-col grid */
  #result-area { grid-template-columns: repeat(auto-fill, minmax(max(80px, calc(50% - 6px)), 1fr)); }

  /* Cards — seamless on mobile */
  .glass-card { margin: 0; border-radius:0; }

  /* Field rows — stack vertically */
  .field-row { flex-direction: column; align-items: stretch; }
  .field-row label { min-width: auto; }

  /* Viewer compact */
  #v-controls { padding: 6px 10px 8px; }
  #v-controls-row { flex-wrap: wrap; gap: 4px; }
  #v-prev, #v-next { flex: 1; }
  #v-controls-row button { padding: 4px 6px; font-size: 9px; min-height: 36px; }
  .v-nav-hint { display: none; }
  body { overscroll-behavior-y: contain; }

  /* Gallery filter row — wrap */
  #gallery-filter-row { flex-wrap: wrap; gap: 4px; }
  /* Full-width search on its own line; the presets + action buttons wrap
     beneath instead of squeezing the field down to an unreadable sliver. */
  #gallery-filter-row input[type="text"] { flex: 1 1 100%; order: -1; min-width: 0; }
  #gallery-filter-row #thumb-size-slider { max-width: 60px; }
  #gallery-filter-row .thumb-presets { flex-shrink: 0; }

  /* Smaller topbar */
  .topbar { padding: 0 10px; height: 44px; gap: 8px; }

  /* Wrap everything */
  .gap-row { flex-wrap: wrap !important; }
  .gap-row:has(#width) input { min-width: 45%; }

  /* Settings — full-width sliders */
  .slider-group { flex-wrap: wrap; }
  .slider-group input[type="range"] { min-width: 60px; }

  /* Left tab bar — compact but legible (9px was below the readable floor) */
  .left-tab-btn { font-size: 10px; padding: 6px 5px; min-height: 40px; }
  .left-tab-btn svg { width: 10px; height: 10px; }

  /* Tag panel — fullscreen overlay */
  #tags-panel.tags-panel { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 200; border-radius:0; padding: 12px; margin: 0; overflow-y: auto; background: var(--bg-card); }

  /* Touch-friendly inputs */
  input[type="text"], input[type="number"], textarea, select {
    font-size: 16px;
    min-height: 44px;
  }
  button, .btn, .tags-tab, .workflow-btn {
    min-height: 44px;
    touch-action: manipulation;
  }
  .checkbox-wrap, label { touch-action: manipulation; }

  /* Workflow buttons — wrap into a visible grid. The old horizontal scroller
     clipped the later modes ("Text-to-GIF", "Text-to-Video") behind a fade
     that didn't read as scrollable, so half the workflows were easy to miss. */
  #gen-mode-bar .mode-bar-inner { flex-wrap: wrap; }
  #gen-mode-bar .mode-label { display: none; }
  #gen-mode-bar .mode-bar-inner .workflow-btns {
    flex-wrap: wrap; overflow: visible; width: 100%;
    -webkit-mask-image: none; mask-image: none; padding-right: 0;
  }
  #gen-mode-bar .mode-bar-inner .workflow-btns .workflow-btn {
    flex: 1 1 calc(50% - 3px); min-width: 0; justify-content: center; min-height: 36px;
  }

  /* Overlays — full screen */
  .overlay-content { max-width: 100% !important; margin: 0; border-radius:0; width: 100%; height: 100%; overflow-y: auto; }

  /* img2img dropzone — compact */
  #img2img-dropzone { min-height: 60px; padding: 4px; }

  /* Denoise/res presets — wrap */
  .denoise-presets { flex-wrap: wrap; }
  .res-presets { flex-wrap: wrap; }

  /* Model selector — full width */
  .model-dropdown-row { flex-direction: column; }
  .model-select { width: 100%; font-size: 12px; padding: 8px 6px; }

  /* Load/Unload buttons — stack + full width */
  #system-card .gap-row:first-of-type { flex-direction: column; align-items: stretch; }
  #system-card .gap-row:first-of-type button { width: 100%; }
  #system-card .gap-row:first-of-type #model-load-status { text-align: left; }
}
@media (max-width: 480px){
  .card-header{ padding: 6px 8px; }
  .card-body{ padding: 6px 8px; }
  .slider-group label{ font-size: 10px; min-width: 34px !important; }
  .slider-group input[type="range"]{ flex: 1; }
  /* Keep the 44px touch floor from the 768px block — narrow phones need
     bigger targets, not smaller ones. Only type/padding tighten here. */
  .btn{ font-size: 12px; padding: 0 12px; min-height: 44px; }
  .btn-sm{ font-size: 11px; padding: 0 10px; min-height: 44px; }
  #v-controls-row{ flex-direction: column; align-items: stretch; gap: 4px; }
  #v-controls-row button{ min-height: 44px; }
  .v-group{ justify-content: center; }
  .v-separator{ display: none; }
}
/* ── Very small phones (380px and below) ── */ @media (max-width: 380px){
  #result-area { grid-template-columns: 1fr; }
  .topbar { padding: 0 6px; gap: 4px; }
  .card-header { padding: 4px 6px; }
  .card-body { padding: 4px 6px; }
  #gen-layout { padding: 2px 2px 0; gap: 3px; }
  #gen-left-col { gap: 3px; }
}
/* ── Viewer ── */ #viewer{ display: none; position: fixed; inset: 0; z-index: 999; background: var(--bg); flex-direction: column; } #viewer.show{ display: flex; animation: viewerFadeIn 0.15s ease; }
@keyframes viewerFadeIn { from { opacity: 0; } to { opacity: 1; } }/* Viewer controls — bottom toolbar, auto-hide */ #v-controls{
  position: absolute; bottom: 0; left: 0; right: 0; z-index: 10;
  display: flex; flex-direction: column; gap: 0;
  padding: 8px 16px 10px;
  background: linear-gradient(transparent, rgba(5,5,8,0.85) 30%);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  transition: opacity 0.3s ease, transform 0.3s ease;
} #viewer.viewer-controls-hidden #v-controls{
  opacity: 0; pointer-events: none; transform: translateY(6px);
} #v-exit-row{
  display: flex; align-items: center; justify-content: space-between; gap: 4px; margin-bottom: 6px;
} #v-exit-row button{
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-dim); padding: 3px 8px; border-radius:var(--radius-sm);
  cursor: pointer; font-size: 10px; display: inline-flex; align-items: center;
  gap: 3px; line-height: 1; transition: color 0.12s, background-color 0.12s, border-color 0.12s, box-shadow 0.12s, opacity 0.12s, transform 0.12s, filter 0.12s, fill 0.12s, stroke 0.12s; font-family: var(--font-sans);
} #v-exit-row button:hover{ background: rgba(255,255,255,0.1); color: var(--text); } #v-exit-row button svg{ width: 10px; height: 10px; flex-shrink: 0; } #v-controls-row{
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
} #v-controls-row button{
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.08);
  color: var(--text); padding: 5px 8px; border-radius:var(--radius-sm);
  cursor: pointer; font-size: 11px; display: inline-flex; align-items: center;
  justify-content: center; gap: 3px; line-height: 1; transition: color 0.12s, background-color 0.12s, border-color 0.12s, box-shadow 0.12s, opacity 0.12s, transform 0.12s, filter 0.12s, fill 0.12s, stroke 0.12s;
  font-family: var(--font-sans); white-space: nowrap;
} #v-controls-row button:hover{ background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.14); } #v-controls-row button svg{ width: 12px; height: 12px; flex-shrink: 0; }/* Toolbar groups */ .v-group{ display: flex; align-items: center; gap: 4px; } .v-separator{ width: 1px; height: 18px; background: rgba(255,255,255,0.08); flex-shrink: 0; }/* Nav group */ #v-counter{ font-size: 10px; color: var(--text-dim); font-family: var(--font-mono,monospace); min-width: 40px; text-align: center; white-space: nowrap; }/* Zoom group */ #v-zoom-pct{ font-size: 9px; color: var(--text-dim2); font-family: var(--font-mono,monospace); min-width: 32px; text-align: center; }/* Generate button — primary */ .v-smart-container{ position: relative; display: inline-flex; align-items: center; } .v-smart-btn{
  background: linear-gradient(135deg,rgba(var(--accent-rgb),0.2),rgba(168,139,255,0.12));
  border: 1px solid rgba(var(--accent-rgb),0.3); color: var(--accent);
  padding: 5px 12px; border-radius:var(--radius-sm); cursor: pointer;
  font-size: 11px; display: inline-flex; align-items: center; gap: 4px;
  line-height: 1; font-family: var(--font-sans); transition: color 0.12s, background-color 0.12s, border-color 0.12s, box-shadow 0.12s, opacity 0.12s, transform 0.12s, filter 0.12s, fill 0.12s, stroke 0.12s;
  font-weight: 600;
} .v-smart-btn:hover{ background: rgba(var(--accent-rgb),0.3); border-color: var(--accent); } .v-smart-btn svg{ width: 10px; height: 10px; transition: transform 0.15s; } .v-smart-btn.open svg{ transform: rotate(180deg); }/* Smart dropdown — opens upward */ .v-smart-dropdown{
  display: none; position: absolute; bottom: 100%; left: 50%; margin-bottom: 6px;
  transform: translateX(-50%) translateY(4px) scale(0.97);
  background: var(--bg-elevated); border: 1px solid var(--glass-border-hover);
  border-radius:var(--radius); backdrop-filter: blur(16px);
  box-shadow: 0 -8px 32px rgba(0,0,0,0.5); z-index: 1001;
  min-width: 180px; padding: 3px 0; opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
} .v-smart-dropdown.open{ display: block; opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } .v-smart-item{ padding: 6px 12px; font-size: 11px; color: var(--text); cursor: pointer; display: flex; align-items: center; gap: 6px; transition: color 0.1s, background-color 0.1s, border-color 0.1s, box-shadow 0.1s, opacity 0.1s, transform 0.1s, filter 0.1s, fill 0.1s, stroke 0.1s; white-space: nowrap; } .v-smart-item:hover{ background: rgba(var(--accent-rgb),0.12); color: var(--accent); } .v-smart-item svg{ width: 12px; height: 12px; flex-shrink: 0; }/* Nav hints — arrows on image edges */ .v-nav-hint{
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 80px; display: flex; align-items: center; justify-content: center;
  color: rgba(255,255,255,0.12); cursor: pointer; opacity: 0;
  transition: opacity 0.2s, color 0.15s; z-index: 5; pointer-events: auto;
} #v-body:hover .v-nav-hint{ opacity: 1; } .v-nav-hint:hover{ color: rgba(255,255,255,0.4); } .v-nav-hint svg{ width: 24px; height: 24px; } .v-nav-left{ left: 12px; } .v-nav-right{ right: 12px; }/* Image body */ #v-body{ position: relative; flex: 1; display: flex; align-items: center; justify-content: center; overflow: hidden; cursor: zoom-in; padding: 0; } #v-img-wrap{ display: flex; align-items: center; justify-content: center; } #v-img{ object-fit: contain; transition: transform 0.1s ease, opacity 0.15s ease; max-width: 100%; max-height: 100%; width: auto; height: auto; }/* Swipe hint (mobile) */ #v-swipe-hint{
  position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%);
  color: var(--text-dim); font-size: 10px; opacity: 0;
  transition: opacity 0.5s ease; pointer-events: none; z-index: 5;
  background: rgba(9,11,20,0.7); border: 1px solid rgba(255,255,255,0.06);
} #viewer.show:not(.has-swiped) #v-swipe-hint{ opacity: 1; } #viewer.has-swiped #v-swipe-hint{ opacity: 0; transition: opacity 0.3s; }/* ── Toast (canonical) ──
   Declared three times before (here as a plain toast, again as a "neon glow"
   expansion, and a third unscoped copy inside the finance block). Each copy
   silently overrode the last, so the width caps, transform and success/error
   glows lived in different places. Merged into one definition. */ #toast{
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  min-width: 200px; max-width: 400px;
  background: var(--bg3); color: var(--text);
  padding: 8px 16px; border-radius:var(--radius);
  font-size: 11px;
  z-index: 99999; opacity: 0; overflow: visible;
  transition: opacity .2s ease, transform .2s ease;
  pointer-events: none;
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 4px 20px rgba(0,0,0,.3);
} #toast.show{ opacity: 1; transform: translateX(-50%) translateY(0); } #toast.toast-error{ border-color: var(--red); box-shadow: 0 4px 20px rgba(242,85,90,.15); } #toast::before{
  content: ''; position: absolute; inset: -3px;
  border-radius:calc(var(--radius) + 3px);
  background: transparent; border: 2px solid transparent;
  pointer-events: none; opacity: 0; transition: opacity .4s ease;
} #toast.show::before{
  opacity: 1; border-color: rgba(var(--accent-rgb),.55);
} #toast.toast-error.show::before{
  border-color: rgba(242,85,90,.6);
} #toast.toast-success.show::before{
  border-color: rgba(78,201,160,.6);
}/* ── Model Dropdown ── */ .model-dropdown-row{
  display: flex;
  gap: 4px;
  align-items: center;
  margin-top: 4px;
} .model-select{
  flex: 1;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--glass-border);
  border-radius:var(--radius);
  color: var(--text);
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 4px 6px;
  cursor: pointer;
  min-width: 0;
  outline: none;
} .model-select:focus{
  border-color: var(--border-focus);
} .model-select option{
  background: var(--bg2);
  color: var(--text);
  font-size: 10px;
}

@keyframes neon-pulse {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}/* ── Overlays ── */ .overlay{ display: none; position: fixed; inset: 0; z-index: 9998; background: rgba(8,8,14,0.7); align-items: center; justify-content: center; backdrop-filter: blur(4px); } .overlay.show{ display: flex; animation: viewerFadeIn 0.12s ease; } .overlay-content{ background: var(--bg-card); border: 1px solid var(--glass-border); border-radius:var(--radius); padding: 14px; max-width: 500px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.4); } .overlay-content h3{ margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--text); } .overlay-content textarea{ min-height: 120px; font-size: 11px; }/* ── Misc ── */  .hidden{ display: none !important; } .flex{ display: flex; } .flex-1{ flex: 1; }  .gap-4{ gap: 4px; } .text-dim{ color: var(--text-dim); }  .text-center{ text-align: center; } .gap-row{ display: flex; gap: 6px; align-items: center; } .tag{ display: inline-block; padding: 1px 5px; font-size: 8px; border-radius:var(--radius-xs); background: var(--bg-hover); color: var(--text-dim); margin: 1px; } .vram-bar-wrap{ display: inline-block; width: 60px; height: 4px; background: var(--glass-border); border-radius:var(--radius-xs); overflow: hidden; } .vram-bar-fill{ height: 100%; border-radius:var(--radius-xs); }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes pulse-load { 0%,100% { background-position: 0% 50%; opacity: 1; } 50% { background-position: 100% 50%; opacity: 0.7; } }
@keyframes neonShift { 0% { background-position: 0% 50%; } 100% { background-position: 300% 50%; } }
@keyframes spin { to { transform: rotate(360deg); } }/* ── Subpage tabs: Generate / Image Editor (gen-family pages) ──
   Scoped to the gen page so the tinker-learn stylesheet's later global
   `.sp-tab` accent no longer leaks in and repaints these cyan. */ .subpage-tabs{display:flex;gap:4px;margin-bottom:8px;flex-shrink:0} .sp-tab{
  padding:6px 14px;border-radius:var(--radius-sm);font-size:11px;font-weight:700;
  background:var(--bg-input);border:1px solid var(--glass-border);color:var(--text-dim2);
  cursor:pointer;transition: color .12s, background-color .12s, border-color .12s, box-shadow .12s, opacity .12s, transform .12s, filter .12s, fill .12s, stroke .12s;letter-spacing:.3px;
}

/* ══ Utilities ═══════════════════════════════════════════════════════════════
   For the repeated one-off inline styles across pages (work, financing, …).
   Appended last so, at equal specificity, they keep the precedence the inline
   declaration had. Keep this list small — prefer a component class. */
.grow{ flex: 1; }
.mb-0{ margin-bottom: 0; }
.mt-10{ margin-top: 10px; }
.fs-12{ font-size: 12px; }
.fs-11{ font-size: 11px; }
.fs-10{ font-size: 10px; }
.txt-red{ color: var(--red); }
.txt-dim2{ color: var(--text-dim2); }
.fs-9{ font-size: 9px; }
.mt-6{ margin-top: 6px; }
.w-full{ width: 100%; }
.mono-txt{ font-family: var(--font-mono); }
.ico-inline{ vertical-align: -1px; margin-right: 2px; }
.num-cell{ padding: 2px 6px; text-align: right; font-family: var(--font-mono); }
.pad-cell{ padding: 2px 6px; }
.mono-dim-9{ font-size: 9px; color: var(--text-dim2); font-family: var(--font-mono); }
.dim-center{ color: var(--text-dim); text-align: center; }

/* ══ FIREFOX PERFORMANCE ══════════════════════════════════════════════════
   Firefox composites backdrop-filter (large blurs + saturate()) and
   mask-image on full-viewport fixed elements far more slowly than Chromium.
   Inside Firefox only, drop both so the plate stays cheap to paint; Chromium
   and Safari keep the full glassmorphism. The JS half of this fix (the
   FRAME_MS branch in common.js) gates on the same -moz-appearance probe. */
@supports (-moz-appearance: none){
.topbar,
  .card,
  .info-card,
  .glass-card,
  .glass,
  .term-toolbar,
  .agent-tabs,
  .mobile-keys,
  .forge-modal,
  .forge-cmdk-box,
  .app-modal,
  .app-modal-card,
  .history-item .delete-btn,
  .history-item .fav-btn,
  .history-item .sel-checkbox{
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}
@supports (-moz-appearance: none){
.bg-grid{
    mask-image: none !important;
    -webkit-mask-image: none !important;
  }
}

/* needs-you */
.needs-card{margin-bottom:var(--sp-4)}
.needs-empty{padding:var(--sp-4);color:var(--text-dim);font-size:var(--fs-md)}
.needs-item{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3);border-bottom:1px solid var(--border)}
.needs-item:last-child{border-bottom:0}
.needs-item.needs{box-shadow:inset 3px 0 0 var(--red)}
.needs-item.heads-up{box-shadow:inset 3px 0 0 var(--amber)}
.needs-text{flex:1;min-width:0}
.needs-title{color:var(--text);font-size:var(--fs-md);font-weight:600}
.needs-detail{color:var(--text-dim);font-size:var(--fs-sm);margin-top:2px}
.needs-btn{padding:6px 10px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface);
  color:var(--text);font:inherit;font-size:var(--fs-sm);text-decoration:none;cursor:pointer;white-space:nowrap}
.needs-btn:hover{background:var(--surface-hover)}
.needs-btn.quiet{color:var(--text-dim)}
@media (max-width:700px){.needs-item{flex-wrap:wrap}}

/* Needs-you count on the Dashboard link in the sidebar */
.sidebar-nav a .nav-badge{margin-left:auto;min-width:18px;padding:0 6px;border-radius:var(--radius-pill);background:var(--amber);color:var(--on-accent);font-size:10px;font-weight:700;line-height:18px;text-align:center}
.sidebar-nav a .nav-badge.needs{background:var(--red)}
