/* ============================================================================
   Apps page: the ONE structural stylesheet.

   The page is on the shared `suite` theme set (commons/themes/suite.css) and has
   the same layout in every theme. So this file carries structure only and names
   NO colour: every colour, typeface, radius and weight comes from a custom
   property. There are two sources:
     - the set's one vocabulary, defined once per theme in commons/themes/suite.css:
       a contract token (--page, --ink, --border, --accent) or a set token
       (--suite-*). The shared surfaces (panels, controls, menus, the backdrop,
       status inks) are therefore the same here as on every other page of the set,
       and this page loads no other page's stylesheet to get them;
     - one of SIX page-only tokens that ./themes.css defines once per theme, for what
       only this gallery has and no formula gives: --apps-tilt and --apps-lift-y
       (the card's lean and lift), --apps-chip2..4 (stat chip fills) and
       --apps-kind-game (the Game tag's hue).
   What the gallery alone paints beyond that (the countdown ring, the sparkline, the
   kind tags, the unsaved banner, the dot grid) is DERIVED here from the vocabulary,
   by reference or by a colour mix, so it follows every theme without a palette.
   A rule that exists for one theme only lives in ./themes.css, never here.

   The shared chrome keeps the Git page's class names on purpose (.btn, .mesh,
   .panel, dialog), so the two pages read as one product; ./themes.css carries this
   page's own per-theme rules for them. A name the shared stylesheet
   (commons/craftian-ui.css, loaded for the top bar) also owns is prefixed `apps-`
   (hint, stat, toast).

   Layout: the shared top bar (commons/craftian-topbar.js), a page toolbar, hero, stat chips, controls, a grid of cards, and a side drawer.
   Under 900px the chips go two-up, under 720px the grid is one column and the
   drawer becomes a bottom sheet, and it holds together down to 360px.
   ========================================================================== */

*{margin:0;padding:0;box-sizing:border-box}
html{background:var(--page);overflow-x:hidden;height:auto}
/* The page colour is on <html> only: a background on <body> would paint over the backdrop.
   commons/craftian-ui.css (loaded for the shared top bar) DOES put one on <body>, and lays
   it out as a fixed-height app shell (height:100dvh; overflow:hidden; display:flex). This
   page is a normal scrolling document, so all four are undone here: without overflow-y
   the page could not scroll at all. */
body{
    font-family:var(--suite-font-ui);color:var(--ink);
    background:none;height:auto;display:block;overflow-y:auto;
    min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased;
}
body.locked{overflow:hidden}
button,input,select{font:inherit;color:inherit}
button{cursor:pointer}
a{color:inherit}
.mono{font-family:var(--suite-font-mono)}
[hidden]{display:none !important}
:focus{outline:none}
:focus-visible{outline:2px solid var(--ring);outline-offset:2px;border-radius:var(--suite-radius-sm)}
::selection{background:color-mix(in srgb, var(--accent) 32%, transparent)}
*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb, var(--accent) 30%, transparent) transparent}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.defs{position:absolute}
.ring-a{stop-color:var(--suite-warn)}
.ring-b{stop-color:var(--suite-err)}

/* ---------- atmosphere + panels ---------- */
.mesh{position:fixed;inset:0;z-index:-1;pointer-events:none;background:var(--suite-mesh)}
.mesh::after{
    content:"";position:absolute;inset:0;
    background-image:radial-gradient(color-mix(in srgb, var(--ink) 7%, transparent) 1px, transparent 1.4px);
    background-size:24px 24px;
}
.panel{
    background:var(--suite-panel);
    backdrop-filter:blur(var(--suite-blur));-webkit-backdrop-filter:blur(var(--suite-blur));
    border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius);box-shadow:var(--suite-panel-shadow);
}

/* ---------- page toolbar (under the shared top bar; it scrolls with the page) ---------- */
.apps-pagebar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:12px clamp(10px,3vw,28px) 0;min-height:36px}
.spacer{flex:1}
.search{
    display:flex;align-items:center;gap:9px;flex:1 1 220px;max-width:420px;min-width:0;
    background:var(--suite-ctl);border:var(--suite-bw) solid var(--border);
    border-radius:var(--suite-radius-pill);padding:8px 14px;
    transition:box-shadow .25s,border-color .25s;
}
.search:focus-within{border-color:var(--ring);box-shadow:var(--suite-focus)}
.search svg{width:16px;height:16px;color:var(--ink-faint);flex-shrink:0}
.search input{border:none;background:transparent;font-size:16px;font-weight:var(--suite-fw-item);width:100%;min-width:0}
.search input:focus-visible{outline:none}
.search input::placeholder{color:var(--ink-faint)}
.btn{
    display:inline-flex;align-items:center;justify-content:center;gap:7px;
    border:var(--suite-bw) solid var(--border);background:var(--suite-ctl);
    padding:8px 13px;border-radius:var(--suite-radius-sm);font-weight:var(--suite-fw-strong);font-size:13.5px;
    white-space:nowrap;text-decoration:none;
    transition:transform .35s var(--spring), background .2s, border-color .2s, box-shadow .2s;
}
.btn svg{width:15px;height:15px;flex-shrink:0}
.btn:hover{background:var(--suite-hover);border-color:var(--ring);transform:translateY(-1px)}
.btn:active{transform:scale(.97)}
.btn[disabled]{opacity:.55;cursor:progress;transform:none}
.btn.primary{border-color:transparent;background:var(--primary);color:var(--suite-on-accent);font-family:var(--suite-font-heading);box-shadow:var(--shadow-sm)}
.btn.primary:hover{box-shadow:var(--shadow)}
.btn.sm{padding:5px 10px;font-size:12.5px}
.btn.sm svg{width:13px;height:13px}
.btn.icon{padding:8px;width:36px;height:36px}
.btn.icon svg{width:17px;height:17px}
.btn.ghost{background:transparent;color:var(--ink-soft)}
.btn.danger{color:var(--suite-err-ink);border-color:color-mix(in srgb, var(--suite-err-ink) 40%, transparent)}
.btn.danger:hover{border-color:var(--suite-err-ink);background:var(--suite-err-wash)}
.btn.danger.solid{background:var(--suite-err-wash)}

/* ---------- page ---------- */
main{max-width:1240px;margin:0 auto;padding:22px clamp(10px,3vw,28px) 70px}
.hero{margin:6px 4px 16px}
.hero h1{font-family:var(--suite-font-heading);font-weight:700;font-size:clamp(26px,4vw,36px);line-height:1.1;color:var(--brand-ink)}
.hero h1 b{background:var(--primary);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p{color:var(--ink-soft);font-weight:var(--suite-fw-item);font-size:15px;margin-top:6px;max-width:60ch;line-height:1.5}

.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:16px}
.stats:empty{display:none}
.apps-stat{
    display:flex;align-items:center;gap:12px;padding:12px 14px;min-width:0;
    background:var(--suite-panel);backdrop-filter:blur(var(--suite-blur));-webkit-backdrop-filter:blur(var(--suite-blur));
    border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius);box-shadow:var(--shadow-sm);
}
.apps-stat .ico{width:38px;height:38px;border-radius:var(--suite-radius-sm);display:grid;place-items:center;color:var(--suite-on-accent);flex-shrink:0}
.apps-stat .ico svg{width:18px;height:18px}
.apps-stat.k1 .ico{background:var(--primary)}
.apps-stat.k2 .ico{background:var(--apps-chip2)}
.apps-stat.k3 .ico{background:var(--apps-chip3)}
.apps-stat.k4 .ico{background:var(--apps-chip4)}
.apps-stat b{display:block;font-family:var(--suite-font-heading);font-size:21px;line-height:1.1;color:var(--brand-ink)}
.apps-stat span{font-size:12.5px;font-weight:var(--suite-fw-strong);color:var(--ink-soft)}

.controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px}
.filts{display:flex;gap:6px;flex-wrap:wrap}
.filt{
    border:var(--suite-bw) solid var(--border);background:var(--suite-panel);
    border-radius:var(--suite-radius-pill);padding:6px 14px;font-weight:var(--suite-fw-strong);font-size:13.5px;color:var(--ink-soft);
    transition:transform .45s var(--spring),background .25s,color .25s;
}
.filt:hover{transform:translateY(-2px);background:var(--suite-hover);color:var(--ink)}
.filt[aria-pressed="true"]{background:var(--primary);color:var(--suite-on-accent);border-color:transparent;box-shadow:var(--shadow-sm)}
.filt em{font-style:normal;opacity:.8;margin-left:5px;font-weight:var(--suite-fw-item)}
.sort{
    display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:var(--suite-fw-strong);color:var(--ink-soft);
    background:var(--suite-panel);border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius-pill);padding:3px 6px 3px 13px;
}
.sort svg{width:14px;height:14px}
.sort select{border:none;background:transparent;font-weight:var(--suite-fw-strong);font-size:14px;padding:4px;border-radius:var(--suite-radius-pill);color:var(--ink)}
.sort select option{background:var(--surface);color:var(--ink)}

/* ---------- card gallery ---------- */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(285px,1fr));gap:16px}
.card{
    position:relative;display:flex;flex-direction:column;gap:10px;padding:16px;min-width:0;
    background:var(--suite-panel);backdrop-filter:blur(var(--suite-blur));-webkit-backdrop-filter:blur(var(--suite-blur));
    border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius);
    box-shadow:var(--shadow-sm);
    transform:perspective(900px) translateY(var(--ty,0px)) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
    transition:transform .55s var(--spring),box-shadow .3s,background .3s,border-color .3s;
    will-change:transform;
}
article.card:hover{--ty:var(--apps-lift-y);box-shadow:var(--shadow);background:var(--suite-hover);border-color:var(--ring)}
.card.intro{animation:rise .6s var(--spring) backwards;animation-delay:calc(var(--i) * 45ms)}
@keyframes rise{from{opacity:0;transform:translateY(20px) scale(.96)}}
.card.ghost{min-height:190px}
.card-top{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:30px}
.kind{
    display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:var(--suite-fw-strong);letter-spacing:.3px;
    padding:3px 10px;border-radius:var(--suite-radius-pill);text-transform:uppercase;white-space:nowrap;
}
.kind svg{width:12px;height:12px}
.kind.app{background:var(--suite-accent-soft);color:var(--accent-ink)}
.kind.game{background:color-mix(in srgb, var(--apps-kind-game) 14%, transparent);color:var(--apps-kind-game)}
.status{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:var(--suite-fw-strong);color:var(--ink-soft);white-space:nowrap}
.status i.d{width:8px;height:8px;border-radius:50%;background:var(--ink-faint)}
.status.live{color:var(--suite-ok-ink)}
.status.live i.d{background:var(--suite-ok);box-shadow:0 0 0 4px color-mix(in srgb, var(--suite-ok) 18%, transparent)}
.status.unsaved{color:var(--suite-warn-ink);font-variant-numeric:tabular-nums}
.cring{width:30px;height:30px;transform:rotate(-90deg);flex-shrink:0}
.cring circle{fill:none;stroke-width:4}
.cring .t{stroke:color-mix(in srgb, var(--suite-warn) 18%, transparent)}
.cring .p{stroke:url(#ringGrad);stroke-linecap:round;transition:stroke-dashoffset 1s linear}
.cring.big{width:54px;height:54px}
.card h3{font-family:var(--suite-font-heading);font-size:19px;font-weight:700;line-height:1.2;color:var(--brand-ink);min-width:0}
.card-open{border:none;background:none;text-align:left;font:inherit;color:inherit;max-width:100%;overflow-wrap:anywhere}
.card-open::after{content:"";position:absolute;inset:0;border-radius:var(--suite-radius)}
.card-open:focus-visible{outline:none}
.card-open:focus-visible::after{outline:2px solid var(--ring);outline-offset:2px}
.spark{
    display:flex;align-items:flex-end;gap:3px;height:38px;padding:6px 8px;
    background:var(--suite-tile);border:1px solid var(--line);border-radius:var(--suite-radius-sm);
}
.spark span{flex:1;min-height:3px;border-radius:3px 3px 2px 2px;background:color-mix(in srgb, var(--accent) 40%, transparent);transition:height .5s var(--spring)}
.spark span.w{background:var(--primary)}
.spark span.z{background:color-mix(in srgb, var(--ink-faint) 30%, transparent)}
/* a day nothing is known about: an outline, never a quiet bar */
.spark span.u{background:transparent;border:1px dashed color-mix(in srgb, var(--ink-faint) 30%, transparent);min-height:8px}
.last{font-size:13.5px;font-weight:var(--suite-fw-item);color:var(--ink);display:flex;gap:7px;align-items:baseline;min-width:0}
.last .msg{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}
.last time{color:var(--ink-soft);font-size:12.5px;white-space:nowrap}
.last.none{color:var(--ink-soft)}
.meter{height:7px;border-radius:999px;background:var(--track);overflow:hidden}
.meter span{display:block;height:100%;border-radius:999px;background:var(--primary)}
.meter.hot span{background:var(--suite-warn)}
.meter.cmp span{background:color-mix(in srgb, var(--accent) 40%, transparent)}
.meta{display:flex;justify-content:space-between;gap:8px;flex-wrap:wrap;font-size:12.5px;font-weight:var(--suite-fw-strong);color:var(--ink-soft)}
.meta span{display:inline-flex;align-items:center;gap:4px}
.meta svg{width:12px;height:12px}
.card .keep{position:relative;z-index:2;align-self:flex-start}

.skel{display:block;height:12px;border-radius:999px;background:var(--track);animation:pulse 1.4s ease-in-out infinite}
.skel.tall{height:20px}
.skel.block{height:38px;border-radius:var(--suite-radius-sm)}
.skel.w40{width:40%}
.skel.w70{width:70%}
.skel.w90{width:90%}
@keyframes pulse{50%{opacity:.45}}

.empty{
    grid-column:1/-1;text-align:center;padding:44px 18px;
    background:var(--suite-panel);border:var(--suite-bw) dashed var(--border);border-radius:var(--suite-radius);
}
.empty .bub{width:60px;height:60px;border-radius:var(--suite-radius);background:var(--suite-accent-soft);color:var(--accent-ink);display:grid;place-items:center;margin:0 auto 12px}
.empty .bub svg{width:26px;height:26px}
.empty h3{font-family:var(--suite-font-heading);font-size:19px;color:var(--brand-ink)}
.empty p{color:var(--ink-soft);font-weight:var(--suite-fw-item);margin:6px auto 14px;max-width:46ch;line-height:1.5}

/* ---------- drawer ---------- */
.scrim{position:fixed;inset:0;z-index:50;background:var(--suite-scrim);opacity:0;pointer-events:none;transition:opacity .3s}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{
    position:fixed;z-index:60;top:12px;right:12px;bottom:12px;width:min(740px,calc(100vw - 24px));
    display:flex;flex-direction:column;
    background:var(--suite-menu);backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);
    border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius);box-shadow:var(--shadow), 0 30px 80px -20px var(--suite-scrim);
    transform:translateX(calc(100% + 30px));visibility:hidden;
    transition:transform .55s var(--spring),visibility 0s .55s;
}
.drawer.on{transform:none;visibility:visible;transition:transform .55s var(--spring)}
.d-inner{display:flex;flex-direction:column;min-height:0;flex:1}
.grab{display:none}
.d-head{padding:18px 20px 12px;display:flex;gap:12px;align-items:flex-start}
.d-head .ti{flex:1;min-width:0}
.d-head h2{font-family:var(--suite-font-heading);font-size:24px;font-weight:700;line-height:1.15;overflow-wrap:anywhere;color:var(--brand-ink)}
.d-head .sub{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:6px}
.d-close{border-radius:50%;flex-shrink:0}
.rename{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-top:10px}
.field{
    display:flex;align-items:center;gap:8px;flex:1;min-width:0;
    background:var(--suite-ctl);border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius-sm);padding:8px 11px;
    transition:border-color .2s, box-shadow .2s;
}
.field:focus-within{border-color:var(--ring);box-shadow:var(--suite-focus)}
.field input{border:none;background:transparent;width:100%;min-width:0;font-size:16px;font-weight:var(--suite-fw-item)}
.field input:focus-visible{outline:none}
.field input::placeholder{color:var(--ink-faint)}
.rename .field{min-width:160px}
.banner{
    margin:0 20px 12px;padding:10px 12px;display:flex;gap:12px;align-items:center;flex-wrap:wrap;
    background:var(--suite-warn-wash);border:var(--suite-bw) solid color-mix(in srgb, var(--suite-warn) 35%, transparent);
    border-radius:var(--suite-radius-sm);font-size:13.5px;font-weight:var(--suite-fw-item);line-height:1.45;
}
.banner .bt{flex:1;min-width:180px}
.banner .bt b{font-size:15px;display:block;color:var(--suite-warn-ink);font-variant-numeric:tabular-nums}
.d-body{flex:1;overflow-y:auto;padding:4px 20px 22px;min-height:0}
.sec{margin-bottom:18px;min-width:0}
.sec h4{font-family:var(--suite-font-heading);font-size:16px;font-weight:700;display:flex;align-items:center;gap:8px;margin-bottom:10px;color:var(--brand-ink)}
.sec h4 svg{width:16px;height:16px;color:var(--accent-ink)}
.note{font-size:13.5px;font-weight:var(--suite-fw-item);color:var(--ink-soft);margin-top:8px;line-height:1.5}
.apps-hint{
    text-align:center;padding:22px 14px;color:var(--ink-soft);font-weight:var(--suite-fw-item);font-size:14px;line-height:1.5;
    border:var(--suite-bw) dashed var(--border);border-radius:var(--suite-radius-sm);
}
.apps-hint .btn{margin-left:6px}
.addr{
    display:flex;align-items:center;gap:8px;padding:6px 6px 6px 14px;min-width:0;
    background:var(--suite-ctl);border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius-pill);box-shadow:var(--shadow-sm);
}
.addr .url{flex:1;min-width:0;font-family:var(--suite-font-mono);font-size:13px;overflow-wrap:anywhere;padding:4px 0;color:var(--suite-link)}
.copy{
    position:relative;display:inline-flex;align-items:center;gap:6px;flex-shrink:0;
    border:none;border-radius:var(--suite-radius-pill);padding:7px 14px;font-weight:var(--suite-fw-strong);font-size:13px;color:var(--suite-on-accent);
    background:var(--primary);box-shadow:var(--shadow-sm);
    transition:transform .45s var(--spring),background .3s,box-shadow .3s;
}
.copy:hover{transform:scale(1.06)}
.copy .ic{display:grid;width:15px;height:15px}
.copy .ic svg{grid-area:1/1;width:15px;height:15px;transition:transform .45s var(--spring),opacity .2s}
.copy .lucide-check{opacity:0;transform:scale(.2) rotate(-120deg)}
.copy.done{background:var(--apps-chip3);transform:scale(1.08)}
.copy.done .lucide-copy{opacity:0;transform:scale(.2) rotate(120deg)}
.copy.done .lucide-check{opacity:1;transform:none}
.spark-dot{position:fixed;width:8px;height:8px;border-radius:50%;pointer-events:none;z-index:200;animation:burst .8s cubic-bezier(.2,.7,.3,1) forwards}
.spark-dot.k1{background:var(--primary)}
.spark-dot.k2{background:var(--apps-chip2)}
.spark-dot.k3{background:var(--apps-chip3)}
.spark-dot.k4{background:var(--apps-chip4)}
@keyframes burst{
    from{transform:translate(-50%,-50%) scale(.3);opacity:1}
    to{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(1.1);opacity:0}
}
.d-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:18px}
.quiet{
    margin-left:auto;display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:var(--suite-fw-item);
    color:var(--ink-faint);text-decoration:none;padding:4px 2px;
}
.quiet svg{width:13px;height:13px}
.quiet:hover{color:var(--ink-soft);text-decoration:underline}
.rows{list-style:none;display:grid;gap:6px}
.row{
    display:flex;gap:10px;align-items:center;padding:10px 12px;min-width:0;
    background:var(--suite-tile);border:var(--suite-bw) solid var(--line);border-radius:var(--suite-radius-sm);
}
.row .main{flex:1;min-width:0}
.row .main b{display:block;font-size:14.5px;font-weight:var(--suite-fw-strong);overflow-wrap:anywhere}
.row .main small{display:flex;gap:8px;flex-wrap:wrap;align-items:center;font-size:12.5px;font-weight:var(--suite-fw-item);color:var(--ink-soft);margin-top:3px}
.av{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;color:var(--suite-on-accent);font-weight:var(--suite-fw-strong);font-size:12px;flex-shrink:0;background:var(--primary)}
.kv{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.kv>div{background:var(--suite-tile);border:var(--suite-bw) solid var(--line);border-radius:var(--suite-radius-sm);padding:11px 13px;min-width:0}
.kv .lbl{display:block;font-size:11.5px;font-weight:var(--suite-fw-strong);letter-spacing:.4px;text-transform:uppercase;color:var(--ink-soft);margin-bottom:5px}
.kv .v{font-weight:var(--suite-fw-strong);font-size:14px;overflow-wrap:anywhere}
.kv .meter{margin-top:7px}

/* ---------- whole-page states ---------- */
.gate{
    margin:8vh auto 40px;width:min(480px,calc(100vw - 24px));padding:28px 24px;
    display:flex;flex-direction:column;gap:12px;align-items:center;text-align:center;
}
.gate > svg{width:34px;height:34px;color:var(--accent-ink)}
.gate h1{font-family:var(--suite-font-heading);font-size:24px;font-weight:700;color:var(--brand-ink)}
.gate p{font-size:14px;color:var(--ink-soft);line-height:1.55}

/* ---------- dialogs + toast ---------- */
dialog{
    margin:auto;width:min(480px,calc(100vw - 24px));color:var(--ink);
    background:var(--suite-menu);border:var(--suite-bw) solid var(--border);border-radius:var(--suite-radius);padding:20px;
    box-shadow:var(--shadow);
}
dialog::backdrop{background:var(--suite-scrim);backdrop-filter:blur(4px)}
dialog[open]{animation:pop .35s var(--spring)}
@keyframes pop{from{opacity:0;transform:scale(.94) translateY(10px)}}
dialog h2{font-family:var(--suite-font-heading);font-size:20px;margin-bottom:6px;color:var(--brand-ink)}
dialog p{font-size:13.5px;color:var(--ink-soft);line-height:1.55}
dialog p b{color:var(--ink);overflow-wrap:anywhere}
dialog p.aside{margin-top:12px;font-size:12.5px}
dialog p.aside a{color:var(--suite-link)}
dialog label{display:block;font-size:12px;font-weight:var(--suite-fw-strong);color:var(--ink-soft);margin:14px 0 6px}
.d-acts{display:flex;justify-content:flex-end;gap:8px;margin-top:18px;flex-wrap:wrap}
.apps-toast{
    position:fixed;left:50%;bottom:22px;transform:translate(-50%,30px);opacity:0;pointer-events:none;z-index:120;
    background:var(--suite-menu);color:var(--brand-ink);border:1px solid var(--suite-ok);border-radius:var(--suite-radius-pill);
    padding:9px 16px;font-size:13.5px;font-weight:var(--suite-fw-strong);display:flex;align-items:center;gap:8px;
    box-shadow:var(--shadow);transition:all .4s var(--spring);max-width:calc(100vw - 24px);
}
.apps-toast.on{opacity:1;transform:translate(-50%,0)}
.apps-toast svg{width:15px;height:15px;color:var(--suite-ok);flex-shrink:0}
.apps-toast.err{border-color:var(--suite-err)}
.apps-toast.err svg{color:var(--suite-err)}

/* ---------- responsive ---------- */
@media (max-width:900px){
    .stats{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:720px){
    .apps-pagebar{margin-top:8px;gap:8px}
    .apps-pagebar .search{flex:1 1 0;max-width:none}
    .apps-pagebar .spacer{display:none}
    .grid{grid-template-columns:minmax(0,1fr)}
    .drawer{
        top:auto;left:0;right:0;bottom:0;width:100%;height:92dvh;max-height:92vh;
        border-radius:var(--suite-radius) var(--suite-radius) 0 0;border-bottom:none;transform:translateY(calc(100% + 30px));
    }
    .grab{display:block;width:44px;height:5px;border-radius:999px;background:var(--track);margin:9px auto 0;flex-shrink:0}
    .d-head{padding:10px 14px 10px}
    .d-head h2{font-size:21px}
    .banner{margin-left:14px;margin-right:14px}
    .d-body{padding:4px 14px 22px}
    .kv{grid-template-columns:minmax(0,1fr)}
    .addr{flex-wrap:wrap;border-radius:var(--suite-radius-sm);padding:8px 10px}
    .addr .url{flex-basis:100%}
    .quiet{margin-left:0}
}
@media (max-width:400px){
    .apps-stat{padding:10px;gap:9px}
    .apps-stat .ico{width:32px;height:32px}
    .apps-stat b{font-size:18px}
    .btn.primary .lbl{display:none}
    .controls .spacer{display:none}
}
@media (prefers-reduced-motion:reduce){
    *,*::before,*::after{animation:none !important;transition:none !important}
    .card{transform:none !important}
    .spark-dot{display:none}
}
