/* App shell shared by every signed-in page (workspace/settings/plugins/help): sidebar
   nav + usage meters + the search-header pattern. Reuses .app-shell/.sidebar/.app-header
   from qawlak.css and .qk-icon from ui.css; nothing here should duplicate those. */
.sidebar-nav{display:grid;gap:2px;margin:var(--space-2) 0}.sidebar-nav a{display:flex;align-items:center;gap:var(--space-3);min-height:44px;box-sizing:border-box;padding:var(--space-2) var(--space-3);border-radius:var(--studio-radius,6px);color:var(--studio-fg-2);font-size:13px;text-decoration:none}.sidebar-nav a:hover{background:var(--studio-fill-hover);color:var(--studio-fg);text-decoration:none}.sidebar-nav a[aria-disabled=true]{opacity:.5;pointer-events:none}.sidebar-nav small{color:var(--studio-fg-3);font-size:12px}
/* The current page is the layer's kashida stroke, not a filled block (APPLIED.png row 3).
   .qk-rail-item keys on aria-current="true"; nav links carry the semantically correct
   aria-current="page", so this one selector aliases it rather than restating the rule. */
.sidebar-nav a[aria-current=page]{color:var(--studio-accent)}
.sidebar-nav .qk-rail-item[aria-current=page]::before{transform:translateY(-50%) scaleY(1)}
.usage-meters{display:grid;gap:12px;padding:var(--space-3) var(--space-3);border-top:1px solid var(--studio-line)}.usage-meter{display:grid;gap:4px}.usage-meter div{display:flex;justify-content:space-between;font-size:12px;color:var(--studio-fg-3)}
.search-header{gap:var(--space-4)}.search-header input[type=search]{max-width:260px}
/* The header search is the only field on the page, so its boundary cannot wait for hover
   the way a dense inspector's can — an unbordered 5%-fill slab reads as decoration.
   --studio-fg-3 is the token the layer itself uses when a field has to stand alone. */
.search-header .qk-field{border-color:var(--studio-fg-3)}.search-header input[type=search]::placeholder{color:var(--color-text-muted)}
.page-main{padding:var(--space-6) var(--space-6);max-width:1100px}.page-main h1{margin-bottom:4px}.page-main .hint{margin:0 0 var(--space-5)}
.settings-section{background:var(--color-surface);border:1px solid var(--color-border);border-radius:14px;padding:var(--space-5);margin-bottom:16px}.settings-section h2{font-size:15px;margin-bottom:4px}.settings-section>p.hint{margin-bottom:16px}
.numbered-steps{list-style:none;margin:0;padding:0;counter-reset:step;display:grid;gap:var(--space-4)}.numbered-steps li{counter-increment:step;padding-inline-start:var(--space-6);position:relative}.numbered-steps li::before{content:counter(step);position:absolute;inset-inline-start:0;top:0;width:26px;height:26px;border-radius:50%;background:var(--color-tint);color:var(--color-tint-text);display:grid;place-items:center;font-size:13px;font-weight:700}.numbered-steps strong{display:block;margin-bottom:2px}.numbered-steps p{margin:0;color:var(--color-text-muted);font-size:14px}

.member-row{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--color-border);font-size:14px}.member-row:first-child{border-top:0}.plan-limits{border:1px solid var(--color-warning);border-radius:12px;padding:var(--space-3) var(--space-4);margin:12px 0}.plan-limits ul{margin:var(--space-2) 0 var(--space-3);padding-inline-start:var(--space-5)}.keep-group{border:0;padding:0;margin:var(--space-3) 0}.keep-group legend{font-weight:600;font-size:14px;margin-bottom:4px}.keep-tick{display:flex;align-items:center;gap:var(--space-3);min-height:44px}.keep-tick input{width:20px;height:20px;margin:0}.keep-actions{display:flex;gap:var(--space-3);flex-wrap:wrap}.keep-actions .qk-btn{min-height:44px}.member-row .badge{margin-inline-start:auto}.member-row button{font-size:12px;padding:var(--space-1) var(--space-2)}
.font-row{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--color-border);font-size:14px}.font-row:first-child{border-top:0}.font-row button{margin-inline-start:auto;font-size:12px;padding:var(--space-1) var(--space-2)}
.sub-tabs{display:flex;gap:4px;border-bottom:1px solid var(--color-border);margin-bottom:var(--space-5);overflow-x:auto}.sub-tabs button{padding:var(--space-3) var(--space-2);font-size:14px;white-space:nowrap}
.settings-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:560px){.settings-grid-2{grid-template-columns:1fr}}
@media(max-width:800px){.page-main{padding:var(--space-5) var(--space-4)}.search-header input[type=search]{display:none}}

/* P3: global command palette (static/palette.js). Native <dialog> for free focus-trap +
   Escape + backdrop-click close, matching #dictionary/#panel elsewhere in this codebase. */
#command-palette{padding:0;border:0;border-radius:14px;width:min(560px,92vw);top:14%;background:var(--color-surface);color:var(--color-text);box-shadow:var(--studio-float)}
#command-palette::backdrop{background:var(--studio-scrim)}
#command-palette-input{width:100%;border:0;border-bottom:1px solid var(--color-border);border-radius:14px 14px 0 0;padding:var(--space-4) var(--space-4);font-size:15px;outline:none}
#command-palette-input:focus-visible{border-bottom-color:var(--color-action)}
#command-palette-list{max-height:340px;overflow-y:auto;padding:8px}
.command-palette-row{width:100%;display:flex;align-items:center;gap:var(--space-3);border:0;border-radius:8px;padding:var(--space-3) var(--space-3);background:transparent;text-align:start;font-size:14px}
.command-palette-row span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.command-palette-row small{color:var(--color-text-muted);font-size:12px}
.command-palette-row[aria-selected=true]{background:var(--color-tint)}
@media(prefers-reduced-motion:no-preference){#command-palette[open]{animation:qk-palette-in .12s ease-out}}
@keyframes qk-palette-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}

/* Lighthouse a11y: sidebar hint text on the dark shell (was --ink-500 on forest-900, 2.9:1) + underline inline links inside body copy so they do not rely on colour alone. */
.sidebar .hint{color:var(--studio-fg-3)}
.page-main p a:not(.button){text-decoration:underline;text-underline-offset:2px}

/* ============================================================================
   Studio night — the signed-in app is a dark creator surface, not an admin panel.
   Reference: app.kalakar.io home (research/kalakar-app/screenshot-…-15.jpg): near-black
   canvas, cards a step lighter, one accent, content (the video) carries the colour.
   The palette is NOT a second dark style: shell.js sets data-surface="studio" and these
   rules only map the semantic --color-* roles onto the visual-direction agent's measured
   studio ladder in tokens.css (61e56d8), so the editor and the app stay one surface and a
   retune there reaches both. Dark whatever the OS says, and there is no theme button here
   (UX Q1, 10 Oct): studio-theme.js pins data-theme="dark" before paint.
   ========================================================================== */
:root:not([data-theme="light"]) .app-shell{
 --color-bg:var(--studio-bg);
 --color-surface:var(--studio-panel);
 --color-surface-raised:var(--studio-raise);
 --color-text:var(--studio-fg);
 --color-text-muted:var(--studio-fg-3);
 --color-border:var(--studio-line-strong);
 --color-border-strong:var(--studio-line-input);
 --color-action:var(--studio-accent);
 --color-action-hover:var(--lime-400);
 --color-action-text:var(--studio-accent-ink);
 --color-tint:var(--studio-accent-soft);
 --color-tint-text:var(--studio-accent);
 --color-focus:var(--studio-accent);
 --color-success:var(--studio-success);
 --color-warning:var(--studio-warn);
 --color-danger:var(--studio-danger);
 --color-info:var(--studio-info);
 background:var(--studio-bg);
 color:var(--color-text);   /* body's color resolves against :root, so restate it here */
}
:root:not([data-theme="light"]) .app-shell .app-main{background:var(--studio-bg)}
:root:not([data-theme="light"]) .app-shell .app-header{background:var(--studio-bg);border-bottom-color:var(--studio-line-strong)}
:root:not([data-theme="light"]) .app-shell .sidebar{background:var(--studio-panel);border-inline-end:1px solid var(--studio-line-strong)}
:root:not([data-theme="light"]) .app-shell .sidebar-nav a:hover{background:var(--studio-raise)}
:root:not([data-theme="light"]) .app-shell .sidebar-nav a.active{background:var(--studio-raise-2)}
:root:not([data-theme="light"]) .app-shell .sidebar-bottom,
:root:not([data-theme="light"]) .app-shell .usage-meters{border-top-color:var(--studio-line-strong)}
:root:not([data-theme="light"]) .app-shell .language-toggle{border-color:var(--studio-line-strong);color:var(--color-text-muted)}
/* P6-01 publishing rows: the state sits at the far end when the row has no button
   (an unconfigured target), and a target this server cannot reach is dimmed rather
   than hidden — a person should be able to see that TikTok exists and why it is off. */
.font-row .hint{margin-inline-start:auto;text-align:end}
.font-row.is-unavailable>span{color:var(--color-text-muted)}   /* D14-11: dimmed by colour; opacity took the state text to 2.95:1 */

/* UX 4.2: menu icons at 16px (they were 11-13px and faint); the current page's icon takes the lime with its label. */
.sidebar .qk-icon:not(.qk-icon--lg){width:16px;height:16px}
/* UX 5.3 (Karan Q3): Lessons, Academy and Help are one "Learn" menu item; these tabs move between the three pages. */
.learn-tabs a{padding:var(--space-3) var(--space-2);font-size:14px;white-space:nowrap;color:var(--color-text-muted);border-bottom:2px solid transparent;text-decoration:none}
.learn-tabs a:hover{color:var(--color-text);text-decoration:none}
.learn-tabs a[aria-current=page]{color:var(--color-text);border-bottom-color:var(--studio-accent)}

/* Direction C "بصوت عالي" (Karan, 10 Oct) carried through every signed-in page (settings, Learn, plugins, stats,
   referral, Wafa). The colours already arrive through the studio surface (tokens.css); this is the shape and the
   voice: page titles in Kufi Black, panels as 18px forest tiles on a hairline, every button and chip a pill.
   The h1s carry an inline 16px from batch 5, so the size is restated with !important rather than editing nine
   pages and their generated /en/ twins. */
.app-shell .app-header h1{font:var(--studio-display-weight,900) var(--studio-text-panel,26px)/1.4 var(--studio-display-font)!important;letter-spacing:0}
.app-shell .page-main h2{font-weight:700}
.app-shell .settings-section{border-color:var(--studio-line);border-radius:var(--studio-radius-tile,18px);background:var(--studio-panel)}
/* Loop 13, round 10 (Karan, 12 Oct: "less noise"): signed-in pages read as headed sections, not stacked cards. A section
   is its heading and 32px of air, with one hairline between sections; no fill, no outline, no rounded box. */
.app-shell .page-main .settings-section{background:none;border:0;border-top:1px solid var(--studio-line);border-radius:0;padding:var(--space-6) 0;margin:0}
.app-shell .page-main .settings-section:first-of-type,.app-shell .page-main .settings-jump+.settings-section,.app-shell .page-main .sub-tabs+.settings-section{border-top:0;padding-top:8px}
.app-shell :is(.page-main,.app-header) :is(.qk-btn,.qk-cta,.button):not(.qk-iconbtn):not(.qk-tab){border-radius:var(--studio-radius-pill,999px)}
.app-shell .page-main :is(.qk-btn,.qk-cta):not(.qk-iconbtn):not(.qk-tab){min-height:40px;padding-inline:var(--space-4)}
.app-shell :is(.invite-row,.job-row,.unfinished-row,.plan-limits){border-radius:var(--studio-radius-block,12px)}
.app-shell .sidebar-nav a{border-radius:var(--studio-radius-pill,999px)}
.app-shell .sidebar-nav a.active,.app-shell .sidebar-nav a[aria-current=page]{background:var(--studio-raise)}
/* Polish R9: Arabic lists count in Arabic-Indic digits, as every other count on an Arabic page does (i18n.js digits()). */
html[lang=ar] ol:not([class]){list-style-type:arabic-indic}html[lang=ar] .numbered-steps li::before{content:counter(step,arabic-indic)}
/* Loop 12, round 1: every page's sub-tabs (Settings jump bar, Learn, Subscription) speak the editor rail's language —
   36px pills, the current one in lime-soft with the 1.5px lime ring (rail-btn[aria-selected]) instead of an underline. */
.app-shell .page-main .sub-tabs{gap:var(--space-2);border-bottom:0;padding-block:var(--space-2);align-items:center}
.app-shell .page-main .sub-tabs>:is(a,button){display:inline-flex;align-items:center;min-height:36px;padding:0 var(--space-4);border:0;border-radius:var(--studio-radius-pill,999px);background:var(--studio-panel);color:var(--studio-fg-2);font-size:13px;font-weight:500;white-space:nowrap;text-decoration:none;transition:background-color var(--studio-dur-state,160ms) var(--studio-ease-out,ease),color var(--studio-dur-state,160ms) var(--studio-ease-out,ease)}
.app-shell .page-main .sub-tabs>:is(a,button):hover{background:var(--studio-raise);color:var(--studio-fg);text-decoration:none}
.app-shell .page-main .sub-tabs>:is(a[aria-current],button[aria-selected=true]){background:var(--studio-accent-soft);color:var(--studio-fg);box-shadow:inset 0 0 0 1.5px var(--studio-accent);font-weight:600}
@media(pointer:coarse),(max-width:560px){.app-shell .page-main .sub-tabs>:is(a,button){min-height:44px}}
/* Loop 12, round 2: the phone bottom bar on every signed-in page (shell.js builds it from the sidebar links).
   Same shape as the editor's phone rail: 56px items, icon over one word, current in lime-soft, safe-area padding;
   the page and the toast end above it, so nothing sits under the bar. */
.shell-tabbar{display:none}
@media(max-width:560px){
 .shell-tabbar{position:fixed;inset-inline:0;bottom:0;z-index:30;display:flex;gap:4px;padding:6px 4px calc(8px + env(safe-area-inset-bottom));background:var(--studio-panel);border-top:1px solid var(--studio-line)}
 .shell-tabbar a{flex:1 1 0;min-width:0;min-height:56px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--space-2) 0;border-radius:14px;color:var(--studio-fg-2);font-size:12px;font-weight:500;line-height:1.2;text-decoration:none;white-space:nowrap;touch-action:manipulation}
 .shell-tabbar a:hover{background:var(--studio-raise);color:var(--studio-fg);text-decoration:none}
 .shell-tabbar a[aria-current=page]{background:var(--studio-accent-soft);color:var(--studio-fg)}
 .shell-tabbar a:focus-visible{outline:3px solid var(--studio-accent);outline-offset:2px}
 .shell-tabbar .qk-icon{width:22px;height:22px}
 /* Loop 13: icons, and only the current page says its word (the editor bar does the same); the words stay the links' names. */
 .shell-tabbar a:not([aria-current]){font-size:0;gap:0}
 body.has-tabbar{padding-bottom:calc(71px + env(safe-area-inset-bottom))}
 body.has-tabbar #notice{bottom:calc(83px + env(safe-area-inset-bottom))}
}
/* Loop 12, round 23: the referral rules fold under one "Rules" line (the 30-day hold and the paid-plan terms). */
.ledger-rules{margin:4px 0 12px}.ledger-rules summary{cursor:pointer;font-size:13px;font-weight:600;padding-block:var(--space-2);display:list-item}
/* Loop 12, round 27: a row's trailing hint (credit history "Balance 1.2") sits on the row's line at its end, not raised 8px above it. */
.member-row>span.hint{margin:0;margin-inline-start:auto;line-height:inherit}
/* Loop 12, round 37: on touch screens every signed-in page's buttons and pills are at least 44 px tall; the 40 px pill
   sizes (page buttons, header language switch) were overriding ui.css's coarse-pointer 44 px. */
@media(pointer:coarse){.app-shell :is(.qk-btn,.qk-cta,.language-toggle,button,select,input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color])):not(.qk-iconbtn){min-height:44px!important}}   /* a floor, so it wins over every 40 px / 24 px size */
@media(pointer:coarse){.app-shell summary{min-height:44px}}
/* A member row (name, email, role, Remove, Make owner) wraps on a phone instead of pushing the page 10 px wide. */
@media(max-width:560px){.member-row{flex-wrap:wrap;row-gap:8px}}
