/*
 * Student platform components (resources/views/components/ui/*), ported from the owner-approved
 * design page (.superpowers/sdd/2026-10-22-student-platform-redesign/ds-approved/index.html,
 * component CSS lines 154-307). Built to public/css/ui/ui.css by scripts/build-ui.mjs and linked
 * after tokens.css by partials/ui-head.
 *
 * Changes against the approved page:
 *   - variable names: --text -> --ink, --text-2 -> --muted, --border -> --line (tokens.js names);
 *   - the page's demo-only layout helpers (.duo, .panel, .btn-grid, .phone, .desk, .fit, .cards,
 *     .badges, .alerts, .fields ...) and its .is-focus state are not ported. The button .is-hover
 *     state IS here, on the same rule as :hover, so /admin/design's static "hover" cells can never
 *     drift from the real hover colours (this file is their single source);
 *   - top-level classes that would clash with page CSS on the same pages get a ui- prefix:
 *     .track -> .ui-track, .lesson -> .ui-lesson, .prog -> .ui-prog, .pw -> .ui-pw
 *     (qudurat/result.blade.php already has its own .track);
 *   - keyframes are ui-spin / ui-ping / ui-sk, so Tailwind's spin/ping on the same page keep theirs;
 *   - icons are .ui-icon (inline <svg> from App\Support\Icons) instead of the page's .ic sprite;
 *   - .ui-modal is a real fixed overlay (the page draws it inside a panel as an example).
 * No rules on bare elements: only the focus ring and the reduced-motion switch are global.
 * Every colour is a var() from tokens.css (light on :root, dark on :root.dark).
 *
 * Reserved class name: "dark". tokens.css applies the whole dark palette to any element with the
 * class dark (scripts/build-ui.mjs: the forced-dark column of /admin/design), not only to
 * :root.dark. Never give an element class="dark" for anything else on a page that loads
 * partials/ui-head (student, exam and qudurat pages): it would switch that subtree to dark colours.
 */

/* The approved page sets box-sizing:border-box on every element; here it is scoped to the components
   (Tailwind pages already have it, the exam/qudurat layouts may not), so width:100% fields and
   block buttons never overflow their card. */
.ui-btn,.ui-card,.ui-card *,.ui-field *,.ui-alert,.ui-badge,.ui-progress,.ui-empty *,.ui-modal,.ui-modal *,.ui-tabbar,.ui-tabbar *,.ui-topbar,.ui-topbar *,.acct-menu,.acct-menu *{box-sizing:border-box}

/* ---------- Focus ring (Ruling R4): gold outline + a dark-green edge in light mode ---------- */
.ui-btn:focus-visible,.ui-card:focus-visible,a:focus-visible,button:focus-visible{outline:3px solid var(--gold);outline-offset:2px;box-shadow:0 0 0 6px var(--focus-edge)}
.ui-input:focus-visible{outline:3px solid var(--gold);outline-offset:2px;border-color:var(--green);box-shadow:0 0 0 6px var(--focus-edge)}

/* ---------- Icon ---------- */
.ui-icon{flex:none;display:inline-block;vertical-align:middle}
.ui-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---------- Button ---------- */
.ui-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 18px;border-radius:var(--r-ctl);border:1px solid transparent;font:700 15px/1.25 var(--font-head);text-decoration:none;cursor:pointer;white-space:nowrap;transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),transform var(--dur) var(--ease)}
.ui-btn-md{min-height:44px;padding-inline:18px;font-size:15px}
.ui-btn-lg{min-height:52px;padding-inline:24px;font-size:17px}
.ui-btn-block{display:flex;width:100%}
.ui-btn-primary{background:var(--btn-primary);color:var(--on-green)}
.ui-btn-primary:hover,.ui-btn-primary.is-hover{background:var(--btn-primary-hover)}
.ui-btn-gold{background:var(--gold);color:var(--on-gold)}
.ui-btn-gold:hover,.ui-btn-gold.is-hover{background:var(--gold-hover)}
.ui-btn-ghost{background:transparent;color:var(--green);border-color:color-mix(in srgb, var(--green) 40%, var(--surface))}
.ui-btn-ghost:hover,.ui-btn-ghost.is-hover{background:var(--green-soft);border-color:var(--green)}
.ui-btn-danger{background:var(--bad);color:var(--on-bad)}
.ui-btn-danger:hover,.ui-btn-danger.is-hover{background:var(--bad-hover)}
.ui-btn:disabled,.ui-btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed}
.ui-btn[aria-busy="true"]{cursor:progress}
.ui-btn .spin{animation:ui-spin .8s linear infinite}
@keyframes ui-spin{to{transform:rotate(360deg)}}

/* ---------- Card ---------- */
.ui-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);padding:16px;color:var(--ink);display:grid;gap:12px;min-width:0}
.ui-card-lg{padding:22px}
a.ui-card,.ui-card.is-float{box-shadow:var(--shadow);text-decoration:none;transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
a.ui-card:hover,.ui-card.is-float:hover{transform:translateY(-2px);box-shadow:var(--shadow-hover)}

/* ---------- Field ---------- */
.ui-field{display:grid;gap:6px;min-width:0}
.ui-field label{font:600 15px/1.4 var(--font-body);color:var(--ink)}
.ui-input{width:100%;min-height:48px;padding:10px 14px;border:1px solid var(--field-border);border-radius:var(--r-ctl);background:var(--surface);color:var(--ink);font:400 17px/1.4 var(--font-body);transition:border-color var(--dur) var(--ease)}
.ui-input::placeholder{color:var(--muted);opacity:1}
.ui-input[dir="ltr"]{text-align:right;letter-spacing:.04em;font-variant-numeric:tabular-nums}
.ui-field .hint{font-size:13px;color:var(--muted);line-height:1.5}
.ui-field.has-error label{color:var(--bad)}
.ui-field.has-error .ui-input{border-color:var(--bad);border-width:2px;padding:9px 13px}
.ui-field .err{display:flex;gap:6px;align-items:flex-start;font:600 13px/1.5 var(--font-body);color:var(--bad)}
.ui-field .err .ui-icon{width:16px;height:16px;margin-top:2px}
.ui-pw{position:relative}
.ui-pw .ui-input{padding-inline-end:52px}
.ui-pw button{position:absolute;inset-block:2px;inset-inline-end:2px;width:44px;display:grid;place-items:center;border:0;border-radius:10px;background:transparent;color:var(--muted);cursor:pointer}
.ui-pw button:hover{color:var(--green);background:var(--green-soft)}
.ui-pw button .ic-off{display:none}
.ui-pw button[aria-pressed="true"] .ic-on{display:none}
.ui-pw button[aria-pressed="true"] .ic-off{display:block}

/* ---------- Alert ---------- */
.ui-alert{display:grid;grid-template-columns:24px minmax(0,1fr);gap:4px 12px;padding:14px 16px;border-radius:var(--r-ctl);border:1px solid;font-size:15px;line-height:1.55;color:var(--ink)}
.ui-alert .ui-icon{width:22px;height:22px;grid-row:span 2;margin-top:1px}
.ui-alert b{font:800 17px/1.35 var(--font-head)}
.ui-alert-info{background:var(--green-soft);border-color:color-mix(in srgb, var(--green) 30%, transparent)}
.ui-alert-info .ui-icon,.ui-alert-info b{color:var(--green)}
.ui-alert-success{background:var(--good-soft);border-color:color-mix(in srgb, var(--good) 30%, transparent)}
.ui-alert-success .ui-icon,.ui-alert-success b{color:var(--good)}
.ui-alert-warning{background:var(--warn-soft);border-color:color-mix(in srgb, var(--warn) 35%, transparent)}
.ui-alert-warning .ui-icon,.ui-alert-warning b{color:var(--warn)}
.ui-alert-danger{background:var(--bad-soft);border-color:color-mix(in srgb, var(--bad) 35%, transparent)}
.ui-alert-danger .ui-icon,.ui-alert-danger b{color:var(--bad)}

/* ---------- Badge ---------- */
.ui-badge{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:2px 12px;border-radius:var(--r-pill);border:1px solid transparent;font:700 13px/1.2 var(--font-head);white-space:nowrap}
.ui-badge-neutral{background:var(--neutral-bg);color:var(--muted);border-color:var(--line)}
.ui-badge-gold{background:var(--gold-soft);color:var(--on-gold-soft);border-color:color-mix(in srgb, var(--gold) 55%, transparent)}
.ui-badge-good{background:var(--good-soft);color:var(--good)}
.ui-badge-warn{background:var(--warn-soft);color:var(--warn)}
.ui-badge-bad{background:var(--bad-soft);color:var(--bad)}
.ui-badge-live{background:var(--gold);color:var(--on-gold)}
.ui-badge-live .dot{position:relative;width:8px;height:8px;border-radius:50%;background:var(--on-gold)}
.ui-badge-live .dot::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--on-gold);animation:ui-ping 1.6s cubic-bezier(0,0,.2,1) infinite}
@keyframes ui-ping{75%,100%{transform:scale(2.4);opacity:0}}

/* ---------- Progress ---------- */
.ui-progress{display:block;height:8px;border-radius:var(--r-pill);background:var(--track);overflow:hidden}
.ui-progress > span{display:block;height:100%;width:var(--p);background:var(--fill);border-radius:inherit;transition:width 250ms ease-out}
.ui-prog{display:grid;gap:6px}
.ui-prog-row{display:flex;justify-content:space-between;gap:8px;font-size:15px}
.ui-prog-row .k{color:var(--muted)}
.ui-prog-row .v{font-weight:600;font-variant-numeric:tabular-nums}

/* ---------- Empty state ---------- */
.ui-empty{display:grid;grid-template-columns:48px minmax(0,1fr);gap:4px 14px;align-items:start}
.ui-empty .tile{width:48px;height:48px;border-radius:var(--r-ctl);background:var(--green-soft);color:var(--green);display:grid;place-items:center;grid-row:span 3}
.ui-empty b{font:800 17px/1.4 var(--font-head)}
.ui-empty p{margin:0;font-size:15px;color:var(--muted)}
.ui-empty .ui-btn{justify-self:start;margin-top:8px}

/* ---------- Confirm dialog ---------- */
.ui-modal{position:fixed;inset:0;z-index:60;background:var(--scrim);padding:24px 16px;display:grid;place-items:center}
.ui-modal[hidden]{display:none}
.ui-modal .box{background:var(--surface);color:var(--ink);border-radius:var(--r-card);padding:20px;display:grid;gap:12px;max-width:420px;width:100%;box-shadow:var(--shadow-hover)}
.ui-modal h2,.ui-modal h4{margin:0;font:800 20px/1.25 var(--font-head)}
.ui-modal .box p{margin:0;font-size:15px;color:var(--muted)}
.ui-modal .box .msg{font-size:15px;color:var(--muted)}
.ui-modal .box .msg > * + *{margin-top:8px}
.ui-modal .box .tnum{font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.ui-modal .tile{width:48px;height:48px;border-radius:var(--r-control);background:var(--gold-soft);color:var(--on-gold-soft);display:grid;place-items:center}
.ui-modal .acts{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-start}
.ui-modal .acts.col{flex-direction:column}
.ui-modal .acts.col .ui-btn{width:100%}

/* ---------- Loading skeleton ---------- */
.ui-skeleton{display:grid;gap:10px}
.ui-skeleton .sk{border-radius:8px;background:var(--skel);animation:ui-sk 1.4s ease-in-out infinite}
.ui-skeleton .sk-title{width:40%;height:20px}
.ui-skeleton .sk-line{width:70%;height:14px}
.ui-skeleton .sk-bar{width:100%;height:8px}
@keyframes ui-sk{50%{opacity:.55}}

/* ---------- Track card (مسار) ---------- */
.ui-track{grid-template-columns:48px minmax(0,1fr) 24px;align-items:center;gap:14px;color:var(--ink)}
.ui-track .tile{width:48px;height:48px;border-radius:var(--r-ctl);background:var(--green-soft);color:var(--green);display:grid;place-items:center}
.ui-track .body{display:grid;gap:6px;min-width:0}
/* dir="auto" turns a Latin name LTR, so text-align:start would push it left; the site is RTL only,
   so every title stays right-aligned like the Arabic ones, and a long unbroken Latin word wraps
   instead of widening the page at 360 px ("Mega Goal 1 - Unit 1 Test"). Same for .ui-lesson-title. */
.ui-track .t{font:800 20px/1.25 var(--font-head);color:var(--ink);overflow-wrap:anywhere;text-align:right}
.ui-track .m{font-size:15px;color:var(--muted);font-variant-numeric:tabular-nums}
.ui-track .go{color:var(--green)}
.ui-track.soon .tile{background:var(--neutral-bg);color:var(--muted)}
.ui-track.soon .t{color:var(--muted)}
.ui-track-head{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ---------- Lesson card ---------- */
.ui-lesson{gap:14px}
.ui-lesson-top{display:flex;justify-content:space-between;align-items:center;gap:8px}
.ui-lesson-num{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:var(--green-soft);color:var(--green);font:800 17px/1 var(--font-head);font-variant-numeric:tabular-nums}
.ui-lesson-title{margin:0;font:800 20px/1.3 var(--font-head);color:var(--ink);overflow-wrap:anywhere;text-align:right}
.ui-lesson-stats{margin:0;display:grid;gap:10px}
.ui-lesson-stats .row{display:grid;gap:6px;padding:10px 12px;border-radius:var(--r-ctl);background:var(--bg)}
.ui-lesson-stats .kv{margin:0;display:flex;justify-content:space-between;gap:8px;align-items:center}
.ui-lesson-stats dt{font-size:15px;color:var(--muted)}
.ui-lesson-stats dd{margin:0;font:600 15px/1.4 var(--font-body);display:flex;gap:6px;align-items:center}
.ui-lesson-stats dd.muted{color:var(--muted);font-weight:500}
.ui-lesson-stats dd.ok{color:var(--good)}
.ui-lesson-attempts{display:flex;flex-wrap:wrap;gap:6px}
.ui-lesson-attempts .ui-badge{min-height:24px;padding-inline:8px;font-variant-numeric:tabular-nums}
/* Locked state (sequence on): gate-approved #t7 .lesson.locked and .lock-note. */
.ui-lesson[data-locked] .ui-lesson-num{background:var(--neutral-bg);color:var(--muted)}
.ui-lesson[data-locked] .ui-lesson-title{color:var(--muted)}
.ui-lesson-lock{display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:var(--r-ctl);background:var(--bg);color:var(--muted);font-size:15px;line-height:1.5}
.ui-lesson-lock > .ui-icon{margin-top:3px;flex:none}
.ui-lesson-lock b{display:block;font:700 15px/1.4 var(--font-head);color:var(--ink)}
.ui-lesson-lock span{display:block}

/* ---------- Mobile bottom tab bar (Material 3, adapted) ---------- */
.ui-tabbar{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);background:var(--surface);border-top:1px solid var(--line);padding:6px 4px calc(6px + env(safe-area-inset-bottom, 0px));min-height:72px}
.ui-tabbar a{display:grid;justify-items:center;align-content:center;gap:4px;min-height:56px;text-decoration:none;color:var(--muted);font:600 13px/1.2 var(--font-body);border-radius:12px}
.ui-tabbar .pill{position:relative;width:64px;height:32px;border-radius:999px;display:grid;place-items:center;transition:background-color var(--dur) var(--ease)}
.ui-tabbar a[aria-current="page"]{color:var(--green);font-weight:700}
.ui-tabbar a[aria-current="page"] .pill{background:var(--green-soft)}
.ui-tabbar .count{position:absolute;top:-4px;inset-inline-end:8px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:var(--gold);color:var(--on-gold);font:800 13px/20px var(--font-head);text-align:center;border:2px solid var(--surface);box-sizing:content-box}

/* ---------- Desktop top bar ---------- */
.ui-topbar{height:64px;background:var(--head-bg);color:var(--head-fg);display:flex;align-items:center;gap:28px;padding-inline:32px;position:relative}
.ui-topbar .brand{display:flex;align-items:center;gap:10px;color:var(--head-fg);text-decoration:none;font:800 17px/1.2 var(--font-head)}
.ui-topbar .brand img{width:36px;height:36px;border-radius:10px;background:#ffffff;padding:2px}
.ui-topbar .brand small{display:block;font:500 13px/1.2 var(--font-body);color:var(--head-fg-2)}
.ui-topbar nav{display:flex;gap:4px;height:100%}
.ui-topbar nav a{display:flex;align-items:center;gap:8px;padding-inline:14px;color:var(--head-fg-2);text-decoration:none;font:700 15px/1 var(--font-head);border-bottom:3px solid transparent;border-top:3px solid transparent}
.ui-topbar nav a:hover{color:var(--head-fg)}
.ui-topbar nav a[aria-current="page"]{color:var(--head-fg);border-bottom-color:var(--head-gold)}
.ui-topbar .count{min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:var(--head-gold);color:#112f20;font:800 13px/20px var(--font-head);text-align:center}
.ui-topbar .acct{margin-inline-start:auto;display:flex;align-items:center;gap:8px;min-height:44px;padding-inline:14px;border-radius:12px;border:1px solid rgba(250,248,242,.22);background:transparent;color:var(--head-fg);font:700 15px/1 var(--font-head);cursor:pointer}
/* On /my/account the account button is the current page (gate-approved #t11 desktop panel). */
.ui-topbar .acct[aria-current="page"]{border-color:var(--head-gold)}

/* ---------- Account menu ---------- */
.acct-menu{position:absolute;top:60px;inset-inline-end:32px;width:300px;background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow-hover);padding:8px;display:grid;gap:2px;z-index:2}
.acct-menu[hidden]{display:none}
.acct-menu .who{padding:10px 12px;border-bottom:1px solid var(--line);margin-bottom:4px}
.acct-menu .who b{display:block;font:800 17px/1.3 var(--font-head)}
.acct-menu .who span{font-size:13px;color:var(--muted)}
.acct-menu .it{display:flex;align-items:center;gap:10px;min-height:44px;padding-inline:12px;border-radius:10px;color:var(--ink);text-decoration:none;font:600 15px/1 var(--font-body)}
.acct-menu button.it{width:100%;border:0;background:transparent;cursor:pointer;text-align:start}
.acct-menu .it:hover{background:var(--green-soft)}
.acct-menu .it.out{color:var(--bad)}
.acct-menu .it.out:hover{background:var(--bad-soft)}
.acct-menu .switch{margin-inline-start:auto;width:40px;height:24px;border-radius:999px;background:var(--field-border);position:relative}
.acct-menu .switch::after{content:"";position:absolute;top:3px;inset-inline-start:3px;width:18px;height:18px;border-radius:50%;background:var(--surface)}
/* Keyed on .dark as well, so the forced-dark column of /admin/design shows the "on" state too. */
:root.dark .acct-menu .switch,.dark .acct-menu .switch{background:var(--btn-primary)}
:root.dark .acct-menu .switch::after,.dark .acct-menu .switch::after{inset-inline-start:auto;inset-inline-end:3px;background:var(--ink)}

/* ---------- Account page /my/account (gate-approved #t11, CSS lines 533-551) ----------
   Renamed with the ui- prefix: .who-head -> .ui-who, .kv-list -> .ui-kv, .card-h -> .ui-card-h,
   .set-row -> .ui-set-row, .mono-id -> .is-id; .is-missing (muted «غير مسجّل») is ours.
   The switch row shows «غير مفعّل» / «مفعّل على هذا الجهاز» from aria-checked (.is-off/.is-on). */
.ui-who{display:flex;gap:12px;align-items:center}
.ui-who .tile{width:48px;height:48px;border-radius:var(--r-ctl);background:var(--green-soft);color:var(--green);display:grid;place-items:center;flex:none}
.ui-who b{display:block;font:800 20px/1.3 var(--font-head)}
.ui-who span{font-size:13px;color:var(--muted)}
.ui-kv{margin:0;display:grid}
.ui-kv div{display:flex;justify-content:space-between;gap:12px;padding:12px 0;border-top:1px solid var(--line);align-items:center}
.ui-kv dt{font-size:15px;color:var(--muted)}
.ui-kv dd{margin:0;font:600 15px/1.4 var(--font-body);text-align:left}
.ui-kv dd.is-id{font-variant-numeric:tabular-nums;letter-spacing:.06em}
.ui-kv dd.is-missing{font-weight:400;color:var(--muted)}
.ui-card-h{margin:0;font:800 17px/1.3 var(--font-head);display:flex;gap:8px;align-items:center}
.ui-card-h .ui-icon{color:var(--green)}
.ui-set-row{display:flex;align-items:center;gap:12px;min-height:56px;width:100%;padding:0 4px;border:0;background:transparent;color:var(--ink);font:600 15px/1.4 var(--font-body);cursor:pointer;text-align:start;border-radius:10px}
.ui-set-row:hover{background:var(--green-soft)}
.ui-set-row .lbl{flex:1}
.ui-set-row .lbl small{display:block;font-size:13px;color:var(--muted);font-weight:400}
.ui-set-row[aria-checked="true"] .is-off,.ui-set-row:not([aria-checked="true"]) .is-on{display:none}
.ui-switch{position:relative;width:52px;height:32px;border-radius:999px;background:var(--field-border);flex:none;transition:background-color var(--dur) var(--ease)}
.ui-switch::after{content:"";position:absolute;top:4px;inset-inline-start:4px;width:24px;height:24px;border-radius:50%;background:var(--surface);box-shadow:0 1px 2px rgba(0,0,0,.25);transition:inset-inline-start var(--dur) var(--ease)}
.ui-set-row[aria-checked="true"] .ui-switch{background:var(--btn-primary)}
.ui-set-row[aria-checked="true"] .ui-switch::after{inset-inline-start:24px;background:var(--on-green)}

@media (prefers-reduced-motion: reduce){*{transition:none!important;animation:none!important}}
