@charset "UTF-8";
/* ═══════════════════════════════════════════════════════════════
   Madrastna — stylesheet
   One visual identity: school notebook. Cream paper, faint blue lines,
   vertical red margin rule, and yellow highlighter.

   Notes for anyone editing:
   - File is Mobile-first: base styles target phones (320px up),
     then min-width restores tablet/desktop sizes as before.
   - Repeated colors and sizes live under :root below. Edit there.
   - Directions use logical properties (inline-start / inline-end)
     so they work correctly with right-to-left page direction.
   - Animate transform and opacity only, to avoid jank.
   - Lowest supported: iOS 15 WebKit — so dvh must be preceded by a vh
     line, and clamp()/min()/max() plus logical properties are all safe.
   ═══════════════════════════════════════════════════════════════ */

/* ───────────────────────── 1. Variables ───────────────────────── */
/* Every color the site draws with lives here. Section 20 restates the same
   names for the dark theme, so a color written straight into a rule below
   would stay light there and break — always add a token instead. */
:root{
  color-scheme:light;

  /* Colors */
  --paper:#FBFAF6;
  --paper-2:#FDFCF9;
  --card:#FFFFFF;
  --ink:#24409E;
  --ink-deep:#182B6B;
  --graphite:#242830;
  --muted:#6B7280;
  --margin-red:#D8433F;
  --rule:#DCE4F2;
  --line:#E8E5DC;

  /* Yellow highlighter, in four roles.
     --hi sits behind text, so in the dark theme it turns dark while the text
     stays light. --hi-strong is a thin visible stroke, so there it turns
     bright instead. Same color here, opposite jobs there.
     The two -ink tokens are the text drawn on top of --hi: blue for the
     subject pill, red for the logo pill. Both go warm in the dark theme. */
  --hi:#FFE28A;
  --hi-strong:#FFE28A;
  --hi-ink:var(--ink);
  --hi-ink-2:var(--margin-red);

  /* Text on a filled --ink or --margin-red surface */
  --on-accent:#fff;

  /* Interaction and detail */
  --red-hover:#BE3733;
  --border-hover:#CBD5EC;
  --border-dashed:#C9D3E8;
  --player-bg:#000;
  --wa:#1FA855;   /* WhatsApp brand green — same in both themes */

  /* Notice boxes on the donate page */
  --info-bg:#EEF3FF;
  --info-border:#CBD5EC;
  --info-text:var(--ink-deep);
  --warn-bg:#FFF3F1;
  --warn-border:#F0C4BF;
  --warn-text:#8C2825;

  /* Shadows */
  --shadow:0 1px 2px rgba(24,43,107,.06), 0 8px 24px rgba(24,43,107,.07);
  --shadow-lift:0 2px 4px rgba(24,43,107,.08), 0 14px 34px rgba(24,43,107,.10);

  /* Sizing — mobile values. Desktop values are in section 17 below */
  --wrap:1080px;
  --radius:14px;
  --radius-sm:10px;
  --rule-gap:38px;      /* Notebook line spacing */
  --margin-inset:22px;  /* Red margin line inset from the edge */
  --gap:14px;
}

/* ───────────────────────── 2. Base ──────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

/* No scroll-behavior:smooth on purpose: the site has no in-page
   anchors, and smooth scroll made every route change feel like a scroll */
html{-webkit-text-size-adjust:100%}

body{
  font-family:'Almarai','Segoe UI',Tahoma,'Noto Naskh Arabic',sans-serif;
  background:var(--paper);
  color:var(--graphite);
  font-size:1rem;
  line-height:1.8;
  /* dvh handles the Chrome mobile address bar correctly.
     vh line before it is the iOS 15 fallback */
  min-height:100vh;
  min-height:100dvh;
  display:flex;
  flex-direction:column;
  overflow-x:hidden;
}

.ruqaa{font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;line-height:1.6}

a{color:var(--ink);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
/* Cards and buttons are links, but hide the hover underline — including on touch */
.btn:hover,.grade-card:hover,.subject-card:hover,.teacher-card:hover,
.lecture-row:hover,.next-list a:hover,.wa-float:hover,.logo:hover{text-decoration:none}
img{max-width:100%;height:auto;display:block}
button{font-family:inherit;font-size:inherit;cursor:pointer;border:0;background:none;color:inherit}

/* Touch polish: no grey Android flash, no tap delay */
a,button{-webkit-tap-highlight-color:transparent;touch-action:manipulation}

:focus-visible{outline:3px solid var(--ink);outline-offset:3px;border-radius:4px}

.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:18px}

.skip-link{
  position:absolute;inset-inline-start:-9999px;top:0;z-index:60;
  background:var(--ink);color:var(--on-accent);padding:10px 18px;
  border-radius:0;border-end-end-radius:var(--radius-sm);
}
.skip-link:focus{inset-inline-start:0}

/* Utility: notebook paper. Use on limited areas only, not the whole page,
   to avoid heavy repaints while scrolling. */
.paper{
  background-image:repeating-linear-gradient(
    to bottom, transparent 0 calc(var(--rule-gap) - 1px),
    var(--rule) calc(var(--rule-gap) - 1px) var(--rule-gap));
  background-color:var(--paper-2);
}

/* Utility: red margin line */
.margin-line{
  position:absolute;inset-block:0;inset-inline-start:var(--margin-inset);
  width:2px;background:var(--margin-red);
  transform-origin:top;
  animation:draw .55s ease-out both;
}
@keyframes draw{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ───────────────────────── 3. Buttons ────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:12px 22px;border-radius:var(--radius-sm);
  font-weight:700;font-size:.95rem;line-height:1;
  border:1.5px solid transparent;
  /* 44px touch target on mobile — restores natural size on desktop */
  min-height:44px;
  transition:transform .16s ease, background-color .16s ease, border-color .16s ease;
}
.btn:active{transform:translateY(0) scale(.98)}
.btn-sm{padding:9px 16px;font-size:.88rem}
.btn-ink{background:var(--ink);color:var(--on-accent)}
.btn-red{background:var(--margin-red);color:var(--on-accent)}
.btn-ghost{background:var(--card);color:var(--ink);border-color:var(--line)}
.btn-block{width:100%}
.btn[aria-disabled="true"]{
  background:var(--paper-2);color:var(--muted);border-color:var(--line);
  cursor:not-allowed;pointer-events:none;
}

/* Hover effects for mouse only — so they don't stick on touch after tap */
@media (hover:hover){
  .btn:hover{text-decoration:none;transform:translateY(-1px)}
  .btn-ink:hover{background:var(--ink-deep)}
  .btn-red:hover{background:var(--red-hover)}
  .btn-ghost:hover{border-color:var(--ink);background:var(--paper-2)}
}

/* ───────────────────────── 4. Header ───────────────────────── */
.topbar{
  position:sticky;top:0;z-index:40;
  background:var(--paper);
  border-block-end:1px solid var(--line);
}
.topbar-inner{
  max-width:var(--wrap);margin-inline:auto;
  padding-block:12px;
  /* max() with env() for the notch in iPhone landscape */
  padding-inline:max(18px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  display:flex;align-items:center;justify-content:space-between;
  /* Narrow gap on phones: the theme button and the register button already
     take their share, and the logo needs whatever is left */
  gap:10px;
}
/* min-width:0 lets the logo shrink instead of pushing the buttons off-screen */
.logo{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;min-width:0}
.logo-name{font-size:1.45rem;color:var(--ink-deep)}
.logo-sub{
  font-size:.7rem;font-weight:700;color:var(--hi-ink-2);
  background:var(--hi);padding:2px 8px;border-radius:20px;line-height:1.7;
  overflow-wrap:anywhere;
}

.topbar-actions{display:flex;align-items:center;gap:8px;flex:0 0 auto}

/* Theme switch. The icon shown is the action, not the state: the moon in the
   light theme means press to go dark — matching what aria-label says. */
.theme-toggle{
  flex:0 0 auto;
  width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;
  color:var(--ink);
  background:var(--card);border:1.5px solid var(--line);
  /* Material Symbols draws through ligatures, so a font that never arrives
     leaves the literal word "dark_mode" in the button. This keeps that inside
     the circle instead of breaking the header. */
  overflow:hidden;
  transition:transform .16s ease, border-color .16s ease;
}
.theme-toggle .material-symbols-outlined{
  font-size:22px;line-height:1;
  font-variation-settings:'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 24;
}
.theme-toggle .icon-light{display:none}
html[data-theme="dark"] .theme-toggle .icon-dark{display:none}
html[data-theme="dark"] .theme-toggle .icon-light{display:block}
.theme-toggle:active{transform:scale(.94)}
@media (hover:hover){
  .theme-toggle:hover{border-color:var(--ink)}
}

/* ─────────── 4أ. Notification bell and panel ───────────
   The bell borrows .theme-toggle for its shape so the two circles in the
   header match exactly and stay matched — a second set of size rules would
   drift the first time one of them is touched.

   The panel is fixed, not absolutely positioned under the button: on a
   phone it is a full-width sheet under the header, and from 769px it
   narrows and tucks under the bell. Its top is measured and set by app.js
   at the moment it opens, because the header is a different height on a
   phone and on a desktop and the value has to be right in both.

   Only tokens, so section 20 needs nothing for this block. */
/* overflow:visible undoes what .theme-toggle sets. That rule exists to keep
   a missing icon font from spilling the literal word "dark_mode" out of the
   circle — but the badge below is positioned deliberately OUTSIDE the
   circle, and inheriting the clip would slice it on two edges. The bell
   draws an inline SVG, so it has nothing to spill in the first place. */
/* ── `hidden` needs saying out loud whenever a class sets display ──
   The browser's own [hidden]{display:none} loses to any class rule that
   sets display, because a class outranks an attribute on its own. The bell
   inherits display:grid from .theme-toggle and the panel sets display:flex,
   so without the two rules below the `hidden` attribute this file's JS
   writes does nothing at all: the panel is open from the first paint and
   the close button removes an attribute that was never doing anything.
   chat.css carries the same five rules for the same reason. */
.bell[hidden]{display:none}
.nt-panel[hidden]{display:none}

.bell{position:relative;overflow:visible}
.bell svg{width:22px;height:22px;display:block}

/* The count, not just a dot. "3" answers "is it worth opening" and a bare
   dot does not. It sits on the circle's edge, so it costs no layout space. */
.bell-dot{
  position:absolute;inset-block-start:-2px;inset-inline-end:-2px;
  min-width:18px;height:18px;padding-inline:4px;
  border-radius:9px;
  background:var(--margin-red);color:#fff;
  font-size:.68rem;font-weight:800;line-height:18px;text-align:center;
  border:2px solid var(--paper);
}

.nt-panel{
  position:fixed;z-index:60;
  inset-block-start:64px; /* replaced with the measured value on open */
  inset-inline:10px;
  max-height:min(70vh, 460px);
  display:flex;flex-direction:column;
  background:var(--card);
  border:1px solid var(--line);border-radius:14px;
  box-shadow:0 14px 40px rgba(0,0,0,.18);
  overflow:hidden;
}
/* ── The header is a label, not a heading ──
   It was drawn at the same weight and the same --ink-deep as an
   announcement's own title, so "الإشعارات" and the first title below it
   read as one run of text and nothing marked where the panel's chrome
   ended and its content began. Small, spaced and muted, it now names the
   box and gets out of the way — the loudest thing in the panel should be
   the announcement, which is the only part anyone came to read. */
.nt-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:11px 16px;
  border-block-end:1px solid var(--line);
  background:var(--paper);
  font-size:.75rem;font-weight:800;letter-spacing:.06em;
  color:var(--muted);
}
.nt-x{
  width:32px;height:32px;border-radius:50%;
  display:grid;place-items:center;
  color:var(--muted);background:transparent;border:0;
  font-size:1rem;cursor:pointer;
}
.nt-body-wrap{overflow-y:auto;-webkit-overflow-scrolling:touch}

.nt-list{list-style:none;margin:0;padding:0}
.nt-item{padding:16px}

/* ── The divider between announcements ──
   A real rule, not the item's own border: a "new" item carries a background
   and a red edge, and hanging the separator off the item made the line stop
   and start with those instead of running the full width. As a ::before on
   every item but the first, it is one continuous rule between any two
   announcements whatever state they are in — and there is never a stray
   line above the first or below the last. */
.nt-item + .nt-item{position:relative}
.nt-item + .nt-item::before{
  content:"";position:absolute;
  inset-block-start:0;inset-inline:16px;
  height:1px;background:var(--line);
}

/* The notebook's red margin line, doing a job: it marks what is new */
.nt-item.is-new{
  border-inline-start:3px solid var(--margin-red);
  background:var(--paper-2);
}
/* Bigger than the label above it, so the eye lands here first */
.nt-title{
  font-size:1.02rem;font-weight:800;color:var(--ink-deep);line-height:1.75;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
}
.nt-new{
  font-size:.65rem;font-weight:800;
  background:var(--hi);color:var(--hi-ink-2);
  padding:1px 8px;border-radius:20px;
}
/* ── The announcement itself ──
   No ruled lines behind it: the project rule is that they tire the eye
   behind running text, and this is exactly that.

   And --graphite, not --muted. This is the thing the student opened the
   panel to read; muted grey belongs to the timestamp under it, which is
   context. With both muted the announcement sank to the level of its date. */
.nt-body{
  margin-block-start:5px;
  font-size:.93rem;line-height:1.95;color:var(--graphite);
  white-space:pre-line; /* the dashboard promises a new line stays a new line */
  overflow-wrap:anywhere;
}
.nt-time{
  margin-block-start:8px;
  font-size:.75rem;font-weight:700;color:var(--muted);
}
.nt-empty{padding:30px 20px;text-align:center;color:var(--muted);line-height:1.9}
.nt-empty span{display:block;font-size:.85rem;margin-block-start:4px}


/* ───────────────── 5. Hero — home page surface ───────────── */
.hero{
  position:relative;overflow:hidden;
  border-block-end:1px solid var(--line);
}
.hero-inner{
  max-width:var(--wrap);margin-inline:auto;
  padding-block:40px 44px;
  padding-inline:calc(var(--margin-inset) + 22px) 18px;
  animation:rise .5s ease-out .12s both;
}
.hero-eyebrow{
  display:block;margin-block-end:8px;
  font-size:clamp(1.15rem, 2.6vw, 1.5rem);
  font-weight:700;color:var(--ink-deep);line-height:1.6;
}
.hero h1{
  font-size:clamp(1.9rem, 5.4vw, 3.2rem);
  color:var(--ink-deep);max-width:20ch;
}
.hero h1 mark{
  background:linear-gradient(transparent 56%, var(--hi) 56%);
  color:inherit;padding-inline:4px;
}
.hero-lead{color:var(--muted);font-size:1rem;max-width:56ch;margin-block-start:12px}

/* ───────────────────── 6. Section titles ─────────────────────── */
.section{padding-block:32px}
.section + .section{padding-block-start:0}

.section-title{
  font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.35rem;color:var(--ink-deep);line-height:1.6;
  padding-inline-start:16px;
  border-inline-start:3px solid var(--margin-red);
  margin-block-end:6px;
}
.section-note{color:var(--muted);font-size:.94rem;margin-block-end:22px;padding-inline-start:19px}

/* Never use letter-spacing here — spacing breaks Arabic letter joining */
.eyebrow{
  display:flex;align-items:center;gap:12px;
  font-size:.82rem;font-weight:800;
  color:var(--muted);text-transform:none;
  margin-block:28px 14px;
}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--line)}

/* ───────────────────── 7. Grids and cards ────────────────────── */
.grid{display:grid;gap:var(--gap)}
/* Single column on mobile — multi-column layouts are in section 17 below */
.grid-3,.grid-2{grid-template-columns:1fr}

/* Grade card — looks like a notebook cover */
.grade-card{
  position:relative;overflow:hidden;
  display:block;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);
  padding:18px 20px 16px;
  box-shadow:var(--shadow);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.grade-card::before{  /* Light lines at the top of the card */
  content:"";position:absolute;inset-block-start:0;inset-inline:0;height:64px;
  background-image:repeating-linear-gradient(to bottom,
    transparent 0 20px, var(--rule) 20px 21px);
  opacity:.7;pointer-events:none;
}
.grade-card::after{  /* Red margin line inside the card */
  content:"";position:absolute;inset-block:0;inset-inline-start:14px;
  width:2px;background:var(--margin-red);opacity:.85;
}
.grade-card .g-name{
  position:relative;font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.32rem;color:var(--ink-deep);line-height:1.5;
}
.grade-card .g-go{
  position:relative;display:inline-block;margin-block-start:12px;
  font-size:.88rem;font-weight:700;color:var(--ink);
}

/* Subject card */
.subject-card{
  position:relative;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:20px 22px;box-shadow:var(--shadow);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.subject-card .s-name{font-weight:800;font-size:1.15rem;color:var(--ink-deep)}
.subject-card .s-meta{color:var(--muted);font-size:.88rem;margin-block-start:2px}
.subject-card.is-empty{opacity:.62;box-shadow:none}

/* Avatar */
.avatar{
  flex:0 0 auto;
  width:50px;height:50px;border-radius:50%;
  background:var(--ink);color:var(--on-accent);
  display:grid;place-items:center;
  font-weight:800;font-size:1.2rem;line-height:1;
  overflow:hidden;
}
.avatar img{width:100%;height:100%;object-fit:cover}
.avatar-lg{width:76px;height:76px;font-size:1.8rem}

/* Teacher card in the list */
.teacher-card{
  display:flex;align-items:center;gap:13px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;box-shadow:var(--shadow);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.teacher-card .t-name{font-weight:800;font-size:1.1rem;color:var(--ink-deep)}
.teacher-card .t-meta{color:var(--muted);font-size:.88rem}

/* Light press on touch instead of hover */
.grade-card:active,.subject-card:active,.teacher-card:active{transform:scale(.99)}
.subject-card.is-empty:active{transform:none}

@media (hover:hover){
  .grade-card:hover{
    text-decoration:none;transform:translateY(-3px);
    box-shadow:var(--shadow-lift);border-color:var(--border-hover);
  }
  .subject-card:hover{
    text-decoration:none;transform:translateY(-3px);
    box-shadow:var(--shadow-lift);border-color:var(--border-hover);
  }
  .subject-card.is-empty:hover{transform:none;box-shadow:none;border-color:var(--line)}
  .teacher-card:hover{
    text-decoration:none;transform:translateY(-3px);
    box-shadow:var(--shadow-lift);border-color:var(--border-hover);
  }
}

/* ─────────── 7د. WhatsApp community card — home page ───────────
   Closes the home page. Green is the whole point: --wa already exists and
   is the same value in both themes, and the colour tells a student the
   button leaves for WhatsApp before they read the label.

   Everything else is a token, so section 20 needs no rules for this block.
   The layout stacks on a phone and goes to a row from 769px, where the
   button can sit beside the text instead of under it. */
.wa-card{
  display:flex;flex-direction:column;gap:14px;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);
  padding:20px;
}
.wa-card-icon{
  width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;flex:0 0 auto;
  background:var(--wa);color:#fff;
}
.wa-card-icon svg{width:26px;height:26px;display:block}
.wa-card-title{
  font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.25rem;line-height:1.7;color:var(--ink-deep);
  /* A community name can be long and is typed in the dashboard */
  overflow-wrap:anywhere;
}
.wa-card-text{
  margin-block-start:4px;
  font-size:.94rem;line-height:1.9;color:var(--muted);
}
.wa-card-btn{
  align-self:flex-start;
  display:inline-flex;align-items:center;gap:9px;
  background:var(--wa);color:#fff;border-color:var(--wa);
}
.wa-card-btn svg{width:20px;height:20px;flex:0 0 auto}
@media (hover:hover){
  .wa-card-btn:hover{filter:brightness(1.07);text-decoration:none;color:#fff}
}

/* ─────────── 7ج. Timetable cards — home page ───────────
   A schedule is a picture with writing in it, so the card is mostly picture
   and the name is a caption under it, not a heading over it.

   `object-fit:cover` inside a fixed 4/3 box, not the image's own ratio: the
   schedules come from a phone camera, a scan and a screenshot, so their
   ratios never match — and three cards of three different heights read as a
   broken page rather than a set. The crop is safe because the card is only
   ever the way IN: the tap opens the full image uncropped.

   Only tokens here, so section 20 needs no rules of its own. */
.tt-card{margin:0}

.tt-shot{
  position:relative;overflow:hidden;
  aspect-ratio:4/3;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);
  cursor:zoom-in;
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.tt-shot img{width:100%;height:100%;object-fit:cover;display:block}

.tt-name{
  padding-block-start:10px;
  font-weight:700;font-size:1rem;line-height:1.6;
  color:var(--ink-deep);text-align:center;
}

@media (hover:hover){
  .tt-shot:hover{
    transform:translateY(-3px);
    box-shadow:var(--shadow-lift);border-color:var(--border-hover);
  }
}

/* ─────────── 7أ. Teacher rail — home page ───────────
   Five faces on the home page instead of a link to a list. A scroller and
   not a grid, because the card cut off by the screen edge is what tells the
   student there are more — and it tells them without a word of instruction
   or an arrow to notice.

   No JavaScript touches this, deliberately. Scrolling a horizontal strip in
   an RTL page is a standing trap: scrollLeft runs negative, browsers
   disagreed about its sign for years, and every hand-written carousel meets
   it. The trap belongs to code that drives the scroll itself. CSS
   scroll-snap has none of it, in either direction. */
.t-rail{
  display:flex;gap:var(--gap);
  overflow-x:auto;
  /* Stops the sideways swipe from turning into browser back-navigation */
  overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  /* Out to the screen edges and back in again: a card can now sit flush
     with the edge — which is what makes the cut look deliberate — while the
     first card still lines up with the heading above it */
  margin-inline:-18px;padding-inline:18px;
  padding-block:4px 10px; /* room for the hover lift and its shadow */
  scrollbar-width:none;
}
.t-rail::-webkit-scrollbar{display:none}

.t-tile{
  flex:0 0 auto;width:150px;
  scroll-snap-align:start;
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px 12px 16px;box-shadow:var(--shadow);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
/* Wins over the 401px .avatar rule on specificity, not on order */
.t-tile .avatar{width:72px;height:72px;font-size:1.7rem}

/* Two lines for the name and one for the subject, always — clamped rather
   than left to the content. A fixed pixel height would break the moment a
   name runs long or a student raises their font size; this holds every card
   in the row to the same height without ever setting one. */
.t-tile-name{
  font-weight:800;font-size:.98rem;color:var(--ink-deep);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;min-height:3em;
}
.t-tile-meta{
  color:var(--muted);font-size:.8rem;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;
  overflow:hidden;
}
.t-tile:active{transform:scale(.99)}

.t-rail-foot{margin-block-start:18px}
.t-rail-foot .btn{width:100%}

@media (hover:hover){
  .t-tile:hover{
    text-decoration:none;transform:translateY(-3px);
    box-shadow:var(--shadow-lift);border-color:var(--border-hover);
  }
}

@media (min-width:401px){
  .t-tile{width:164px}
  .t-tile .avatar{width:80px;height:80px;font-size:1.9rem}
}

@media (min-width:769px){
  /* The wrap already has its own gutter here, and the row fits without
     bleeding past it */
  .t-rail{margin-inline:0;padding-inline:0}
  .t-tile{width:180px}
  .t-rail-foot{text-align:center}
  .t-rail-foot .btn{width:auto}
}

/* ─────────── 7ب. Teacher schedule ───────────
   Weekly slots on the teacher page. Ordered from today forward, so the
   first row is normally the answer to "when is the next one".

   Tokens only — no literal colour anywhere here, so the dark theme
   follows with no rules of its own in section 20. */
.slot-list{list-style:none;display:grid;gap:10px}

.slot{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;
}
.slot-dot{
  width:10px;height:10px;border-radius:50%;flex:none;
  background:var(--border-hover);
}
.slot-when{flex:1;min-width:130px}
.slot-day{display:flex;align-items:center;gap:8px;font-weight:800;color:var(--ink-deep)}
.slot-time{color:var(--muted);font-size:.92rem;margin-block-start:2px}

/* The grade is what answers "is this one mine?" — a teacher with courses
   in two grades has slots for both, and without this the student is
   reading someone else's timetable. */
.slot-grade{
  display:inline-block;
  background:var(--hi);color:var(--hi-ink);
  font-size:.8rem;font-weight:700;
  padding:4px 10px;border-radius:999px;
}
.slot-grade-all{background:var(--info-bg);color:var(--info-text)}

.slot-badge,.slot-live{
  font-size:.72rem;font-weight:800;
  padding:3px 9px;border-radius:999px;
}
.slot-badge{background:var(--info-bg);color:var(--info-text)}
.slot-live{background:var(--margin-red);color:var(--on-accent)}

.slot.is-today{border-color:var(--border-hover)}
.slot.is-today .slot-dot{background:var(--ink)}

.slot.is-live{border-color:var(--margin-red);box-shadow:var(--shadow)}
.slot.is-live .slot-dot{
  background:var(--margin-red);
  animation:slot-pulse 1.6s ease-in-out infinite;
}
@keyframes slot-pulse{
  0%,100%{opacity:.4;transform:scale(1)}
  50%{opacity:1;transform:scale(1.25)}
}
@media (prefers-reduced-motion:reduce){
  .slot.is-live .slot-dot{animation:none;opacity:1}
}

.slot-join{flex:none}
.slot-foot{
  color:var(--muted);font-size:.85rem;
  margin-block-start:12px;padding-inline-start:19px;
}

/* On a phone the join button drops to its own full-width line rather than
   being squeezed beside the day and the grade */
@media (max-width:520px){
  .slot-join{width:100%}
}

/* ───────────────────── 8. Teacher page ────────────────────────── */
.profile{
  /* ارتفاع الغلاف متغيّر واحد لأن تلات حاجات لازم تتفق عليه: الشريط نفسه،
     وبداية خط الهامش الأحمر، وقد إيه الأفاتار بيطلع فوقه. لو بقى ثلاث
     أرقام متفرقة، أول تعديل في الارتفاع بيكسر الاتنين التانيين. */
  --cover-h:clamp(118px, 26vw, 176px);
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);
  margin-block-start:14px;
}

/* ── غلاف المدرس ──
   الكارت ورقة كشكول: خطوط ومسطرة وخط هامش أحمر. الغلاف مش بيلغي الفكرة
   دي، بيتحط فوقها — صورة مدبّسة على أول الورقة، والورقة بتكمّل تحتها. */
.p-cover{
  position:relative;height:var(--cover-h);
  background:var(--paper-2);
  border-block-end:1px solid var(--line);
}
.p-cover{cursor:zoom-in}
.p-cover img{width:100%;height:100%;object-fit:cover;display:block}
.avatar.is-viewable{cursor:zoom-in}

/* عارض الصورة. فوق كل حاجة تانية في الصفحة — أعلى z-index في الملف هو
   60 (skip-link)، فـ 70 بتضمن إنه فوق الشات والتوب بار كمان. */
.img-view{
  position:fixed;inset:0;z-index:70;cursor:zoom-out;
  display:grid;place-items:center;padding:20px;
  /* ── مقاس الصورة المفتوحة — رقم واحد بيتظبط منه كل حاجة ──
     كانت بتاخد الشاشة كلها (`max-width:100%`)، والمطلوب مش كده: الطالب
     عايز يشوف الوش واضح، مش يقرب عليه لحد ما يملا الشاشة. والصور
     المخزّنة عرضها 800px فعلى الشاشة الكبيرة كانت بتتعرض بمقاسها كامل.

     الصورة بتتحط في مربّع بالمقاس ده وبتتظبط جواه بنسبتها: الطولية
     بتاخد الطول، والغلاف العريض بياخد العرض. والـ min بيخلّي الرقم
     يصغّر لوحده على الموبايل بدل ما نكتب media query.

     والرقم مرفوع (كان 520) عشان الصور اللي فيها كلام تتقرا — مش كل
     صورة وش، فيه إعلانات ومواعيد بتتصوّر. والسقف باقي تحت مقاس الشاشة
     عن قصد: السواد اللي حواليها هو اللي بيقول إن دي صورة مفتوحة
     وإن الضغط جنبها بيقفلها. */
  --view-size:min(640px, 90vw, 76vh);
}
/* السواد طبقة مستقلة عن الصندوق عشان الشفافية تلمسه هو وحده وقت
   الحركة — الصورة لازم تفضل صريحة وهي بتكبر وبترجع، لا تبهت معاه. */
.img-view-veil{position:absolute;inset:0;background:rgb(0 0 0 / .85)}
/* position:relative عشان ترسم فوق الطبقة السودا (اللي فوقها في الترتيب
   لإنها متموضعة) — من غيرها الصورة تختفي تحت السواد. */
.img-view img{
  position:relative;
  max-width:var(--view-size);max-height:var(--view-size);
  border-radius:var(--radius-sm);
  transform-origin:center;
}
/* زرار الإقفال: ركن ثابت فوق الصورة مهما كان مقاسها، و44px هدف لمس
   كامل. لونه أبيض على دايرة غامقة عشان يفضل باين فوق صورة فاتحة أو
   غامقة على السواء — الصور اللي المدرس بيرفعها مش متحكوم في تعريضها. */
.img-view-close{
  position:absolute;
  inset-block-start:calc(10px + env(safe-area-inset-top, 0px));
  inset-inline-end:calc(10px + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));
  width:44px;height:44px;z-index:1; /* فوق الصورة لو امتدّت لحد الركن */
  display:grid;place-items:center;
  border:1px solid rgb(255 255 255 / .35);
  border-radius:50%;
  background:rgb(0 0 0 / .55);
  color:#fff;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.img-view-close:hover{background:rgb(0 0 0 / .78)}
/* الحلقة السودا الافتراضية (\u200E--ink\u200E) بتختفي على خلفية العارض السودا */
.img-view-close:focus-visible{outline:3px solid #fff;outline-offset:2px}
/* مافيش قفل تمرير على <html> هنا عن قصد — `overflow:hidden` كان بيمنع
   التمرير بتغيير الصفحة نفسها (شريط عنوان بيرجع يظهر على الموبايل،
   وشريط تمرير بيختفي على الكمبيوتر) فالمحتوى ورا العارض كان بيتحرّك.
   المنع بقى على أحداث التمرير فوق العارض وحده في `openImageView`. */
/* تدرّج خفيف جهة تحت. الصور اللي المدرس هيجيبها مش متحكوم في تعريضها:
   صورة فاتحة أوي بتخلّي حد الغلاف يختفي في لون الورقة، ودي بتضمن إن
   الفصل بين الصورة والورقة بيبان دايماً مهما كانت الصورة. */
.p-cover::after{
  content:"";position:absolute;inset-inline:0;inset-block-end:0;height:52%;
  background:linear-gradient(to bottom, transparent, rgb(0 0 0 / .22));
}
/* خط الهامش بينزل من تحت الغلاف لا من فوق الكارت — الخط ده بتاع الورقة
   المكتوبة، ولو عدّى على الصورة يبقى شخبطة عليها مش هامش ليها. */
.profile.has-cover .margin-line{inset-block-start:var(--cover-h)}
/* الأفاتار بيركب على الغلاف بنُصّه. الرقم مربوط بارتفاع الأفاتار نفسه
   (76px) وبحشوة .profile-inner (22px)، فبيفضل نُص بالظبط على أي مقاس. */
.profile.has-cover .avatar-lg{
  margin-block-start:-60px;
  /* حلقة بلون الورقة تفصل الأفاتار عن الصورة اللي وراه مهما كان لونها */
  box-shadow:0 0 0 4px var(--paper-2);
}
.profile-inner{
  position:relative;
  padding-block:22px;
  padding-inline:calc(var(--margin-inset) + 20px) 18px;
  display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;
}
.profile h1{font-size:1.4rem;color:var(--ink-deep);line-height:1.5}
/* One chip per subject the teacher actually has a course in, so this
   repeats on the same line — hence the trailing gap and the wrap. */
.profile .p-subject{
  display:inline-block;margin-block-start:4px;margin-inline-end:6px;
  font-weight:800;color:var(--hi-ink);font-size:.95rem;
  background:var(--hi);padding:2px 10px;border-radius:20px;
}
.profile .p-bio{margin-block-start:12px;max-width:60ch;color:var(--graphite)}
.facts{
  list-style:none;display:flex;flex-wrap:wrap;gap:8px 24px;
  margin-block-start:14px;font-size:.92rem;
}
.facts li{color:var(--muted)}
.facts b{color:var(--graphite);font-weight:700}
/* Sits directly under the social links, so it needs a gap wide enough to
   read as its own action rather than the tail of that row. */
.profile .btn-share{margin-block-start:20px}
.btn-share svg{width:18px;height:18px}
.p-links{display:flex;flex-wrap:wrap;gap:8px;margin-block-start:14px}
.p-link{
  width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--card);border:1px solid var(--line);color:var(--ink);
  transition:transform .15s ease,border-color .15s ease,background-color .15s ease;
}
.p-link img{width:22px;height:22px;object-fit:contain}
@media (hover:hover){
  .p-link:hover{border-color:var(--ink);background:var(--paper-2);transform:translateY(-2px)}
}
.p-link:active{transform:scale(.94)}

/* ─────────────── 9. Course and lecture list ─────────────────── */
.crumbs{font-size:.88rem;color:var(--muted);padding-block:12px 4px}
.crumbs a{
  color:var(--muted);
  /* Larger touch target for small links on mobile */
  display:inline-block;padding-block:8px;
}
.crumbs a:hover{color:var(--ink)}
.crumbs .sep{padding-inline:6px;opacity:.6}

.course-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:18px;flex-wrap:wrap;
  padding-block:8px 20px;border-block-end:1px solid var(--line);
}
.course-head h1{font-size:1.35rem;color:var(--ink-deep);line-height:1.5}
.course-head .c-teacher{color:var(--muted);margin-block-start:2px}

.progress{min-width:100%}
.progress-bar{height:8px;border-radius:20px;background:var(--rule);overflow:hidden}
.progress-bar span{display:block;height:100%;background:var(--ink);border-radius:20px;transition:width .3s ease}
.progress-text{font-size:.85rem;color:var(--muted);margin-block-start:6px}

.lectures{list-style:none;margin-block-start:22px;display:grid;gap:10px}
.lecture-row{
  display:flex;align-items:center;gap:14px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:14px 18px;
  transition:border-color .16s ease, transform .16s ease;
}
.lecture-row:active{transform:scale(.99)}
@media (hover:hover){
  /* transform has no logical equivalent — negative offset is reading direction in RTL */
  .lecture-row:hover{text-decoration:none;border-color:var(--ink);transform:translateX(-3px)}
}
.lec-num{
  flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  background:var(--paper-2);border:1.5px solid var(--line);
  display:grid;place-items:center;font-weight:800;font-size:.9rem;color:var(--muted);
}
.lecture-row.done .lec-num{background:var(--ink);border-color:var(--ink);color:var(--on-accent)}
.lecture-row.done .lec-num svg{width:17px;height:17px}
.lec-body{flex:1;min-width:0}
.lec-title{font-weight:700;color:var(--graphite);line-height:1.6}
.lec-meta{font-size:.82rem;color:var(--muted)}
/* Two lines at most: the row is a scan target, not the place to read the
   whole description — the lecture page prints it in full */
.lec-row-desc{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;
  font-size:.85rem;color:var(--muted);line-height:1.75;margin-block-start:3px;
}
.lec-soon{font-size:.8rem;font-weight:700;color:var(--margin-red);white-space:nowrap}
/* شارة النشاط في صف المحاضرة. الاسم بيكتبه المدرس فممكن يطول — القصّ
   بالنقط هنا هو اللي بيمنع اسم طويل من إنه يزقّ العنوان والمدة برّه الصف. */
.lec-tag{
  flex:0 0 auto;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:.78rem;font-weight:800;color:var(--hi-ink);
  background:var(--hi);padding:3px 10px;border-radius:20px;
}

/* ───────────────────── 10. Lecture page ────────────────────── */
.player{
  position:relative;background:var(--player-bg);border-radius:var(--radius);overflow:hidden;
  aspect-ratio:16/9;box-shadow:var(--shadow);
  /* Safari will not clip an iframe to a rounded corner on overflow alone.
     One line, no cost anywhere else — most students are on Chrome/Android,
     this is only for the few who open it in Safari. */
  transform:translateZ(0);
}
.player iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.player-soon{
  aspect-ratio:16/9;display:grid;place-items:center;text-align:center;
  background:var(--paper-2);border:1px dashed var(--border-dashed);border-radius:var(--radius);
  color:var(--muted);padding:20px;
}
.player-soon .ruqaa{font-size:1.3rem;color:var(--ink-deep);display:block;margin-block-end:6px}

.lec-head{padding-block:20px 8px}
.lec-head h1{font-size:1.4rem;color:var(--ink-deep);line-height:1.6}
/* pre-line: the dashboard textarea keeps the teacher's line breaks, and
   esc() escapes markup without turning them into <br> — without this the
   whole description collapses onto one line */
.lec-desc{color:var(--muted);font-size:.94rem;line-height:1.9;white-space:pre-line;padding-block:14px 0}
.lec-actions{display:flex;gap:10px;flex-wrap:wrap;padding-block:16px}

.pdf-frame{
  width:100%;
  /* Flexible height on mobile — vh line before dvh for iOS 15 */
  height:clamp(320px, 60vh, 480px);
  height:clamp(320px, 60dvh, 480px);
  border:1px solid var(--line);
  border-radius:var(--radius);background:var(--card);
}

.next-list{list-style:none;display:grid;gap:8px;margin-block-start:12px}
.next-list a{
  display:flex;gap:10px;padding:11px 14px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);
  font-size:.94rem;
}
.next-list a:active{transform:scale(.99)}
@media (hover:hover){
  .next-list a:hover{text-decoration:none;border-color:var(--ink)}
}
.next-list a[aria-current="true"]{
  background:var(--hi);border-color:var(--hi);color:var(--hi-ink);font-weight:700;
}
.next-list .n{color:var(--muted);font-weight:700;flex:0 0 auto}

/* ───────── 11. Text pages: about, terms, join ────── */
.doc{max-width:74ch;padding-block:12px 40px}
.doc h1{
  font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.35rem;color:var(--ink-deep);line-height:1.5;
  padding-inline-start:16px;border-inline-start:3px solid var(--margin-red);
}
.doc h2{
  font-size:1.2rem;color:var(--ink);margin-block:30px 8px;font-weight:800;
}
.doc p{margin-block-end:12px}
.doc ul,.doc ol{margin-block-end:14px;padding-inline-start:22px}
.doc li{margin-block-end:6px}
.doc .lead{color:var(--muted);margin-block:10px 4px}
.doc .updated{font-size:.85rem;color:var(--muted);margin-block-start:32px;padding-block-start:14px;border-block-start:1px solid var(--line)}

/* Supervision team cards
   min(300px,100%) instead of 300px so a card never exceeds the screen width */
.people{display:grid;gap:var(--gap);grid-template-columns:repeat(auto-fill,minmax(min(300px,100%),1fr));margin-block-start:22px}
.person{
  position:relative;overflow:hidden;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:26px 24px;box-shadow:var(--shadow);text-align:center;
}
.person::after{
  content:"";position:absolute;inset-block:0;inset-inline-start:14px;
  width:2px;background:var(--margin-red);opacity:.75;
}
.person .avatar{margin-inline:auto;width:160px;height:160px;font-size:3.2rem}
.person h3{font-size:1.2rem;color:var(--ink-deep);margin-block-start:14px}
.person .role{
  display:inline-block;margin-block-start:6px;font-size:.85rem;font-weight:700;
  color:var(--ink);background:var(--paper-2);border:1px solid var(--line);
  padding:2px 12px;border-radius:20px;
}
.person .p-text{font-size:.94rem;color:var(--muted);margin-block-start:12px;text-align:start}
.person .p-link{display:inline-block;margin-block-start:10px;font-size:.9rem;color:var(--ink);padding-block:6px}

/* Join cards */
.join-cards{display:grid;gap:var(--gap);grid-template-columns:repeat(auto-fill,minmax(min(300px,100%),1fr));margin-block-start:24px}
.join-card{
  position:relative;overflow:hidden;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:26px 24px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;
}
.join-card::before{
  content:"";position:absolute;inset-block-start:0;inset-inline:0;height:56px;
  background-image:repeating-linear-gradient(to bottom,transparent 0 18px,var(--rule) 18px 19px);
  opacity:.6;pointer-events:none;
}
.join-card h2{position:relative;font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;font-size:1.4rem;color:var(--ink-deep)}
.join-card .j-text{position:relative;color:var(--muted);font-size:.95rem;margin-block-start:8px}
.join-card ul{position:relative;list-style:none;margin-block:14px;display:grid;gap:7px;font-size:.93rem}
.join-card li{display:flex;gap:9px;align-items:flex-start}
.join-card li::before{content:"—";color:var(--margin-red);font-weight:700;flex:0 0 auto}
.join-card .j-actions{position:relative;margin-block-start:auto;padding-block-start:14px;display:grid;gap:9px}

/* ───────────────────── 12. Donate page ────────────────────── */
.donate-intro{max-width:78ch;padding-block-end:18px}
.donate-methods{padding-block:10px 34px}
.donate-grid{
  display:grid;gap:var(--gap);
  grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));
  margin-block-start:18px;
}
.donate-card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;
}
.donate-card-head{display:flex;align-items:center;gap:10px}
.donate-card-head .material-symbols-outlined{
  flex:0 0 auto;font-size:28px;line-height:1;color:var(--ink);
  font-variation-settings:'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 24;
}
.donate-card h2{
  color:var(--ink-deep);font-size:1.05rem;font-weight:800;line-height:1.55;
}
.donate-value{
  /* Intentional exception: numbers and bank accounts are English, so LTR
     and physical text-align:left on purpose — not a mistake */
  direction:ltr;text-align:left;unicode-bidi:isolate;
  margin-block-start:16px;padding:11px 13px;
  background:var(--paper-2);border:1px solid var(--line);border-radius:var(--radius-sm);
  color:var(--graphite);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.96rem;font-weight:700;line-height:1.5;
  overflow-wrap:anywhere;user-select:all;
}
.donate-note{color:var(--muted);font-size:.88rem;margin-block-start:9px}
.donate-actions{
  display:flex;gap:9px;flex-wrap:wrap;
  margin-block-start:auto;padding-block-start:18px;
}
.donate-actions .btn{min-height:46px;padding-inline:17px;width:100%}

.donate-transparency{
  background:var(--paper-2);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px;box-shadow:var(--shadow);margin-block:10px 18px;
}
.donate-transparency>h2{
  font-family:'Aref Ruqaa','Almarai',serif;font-size:1.55rem;
  color:var(--ink-deep);line-height:1.5;
}
.donate-transparency>p{margin-block-start:8px}
.donate-stats{
  display:grid;grid-template-columns:1fr;gap:10px;
  margin-block:20px;
}
.donate-stats>div{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:14px;text-align:center;
}
.donate-stats span{display:block;color:var(--muted);font-size:.8rem;line-height:1.5}
.donate-stats strong{display:block;color:var(--ink-deep);font-size:1.05rem;margin-block-start:3px}
.donate-transparency h3{font-size:1rem;color:var(--ink);margin-block:18px 8px}
.donate-expenses{list-style:none;display:grid;gap:8px}
.donate-expenses li{
  display:flex;justify-content:space-between;gap:16px;
  padding:9px 12px;background:var(--card);border-radius:var(--radius-sm);
}
.donate-no-expenses{color:var(--muted);font-size:.92rem}
.donate-updated{
  color:var(--muted);font-size:.82rem;
  padding-block-start:12px;border-block-start:1px solid var(--line);
}
.donate-owner,.donate-warning{
  border-radius:var(--radius-sm);padding:14px 16px;font-size:.92rem;font-weight:700;
}
.donate-owner{background:var(--info-bg);border:1px solid var(--info-border);color:var(--info-text)}
.donate-warning{
  background:var(--warn-bg);border:1px solid var(--warn-border);color:var(--warn-text);
  margin-block-start:10px;
}

/* ───────────────────── 13. Empty states ──────────────────── */
.empty{
  text-align:center;padding:48px 22px;
  background:var(--paper-2);border:1px dashed var(--border-dashed);border-radius:var(--radius);
}
.empty .e-title{
  font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.3rem;color:var(--ink-deep);line-height:1.6;
}
.empty p{color:var(--muted);margin-block-start:8px;font-size:.95rem}
.empty .btn{margin-block-start:16px}

/* ─────────────── 13أ. Maintenance mode ──────────────
   The one screen a student sees when the site is switched off from the
   dashboard. Same notebook identity as everything else — a page torn out
   and left on the desk, not a server error.

   Only tokens are used here, so it follows the dark theme with no rules of
   its own in section 20. */
body.is-maintenance .topbar,
body.is-maintenance .footer,
body.is-maintenance .wa-float,
/* The panel is fixed and appended to body, so hiding the header it is
   anchored to leaves it floating over the maintenance screen on its own.
   Maintenance can switch on while it is open — that is exactly the moment
   this covers. */
body.is-maintenance .nt-panel,
body.is-maintenance .install-banner{display:none}

/* The header and footer are gone, so #app is the whole page now */
body.is-maintenance #app{display:flex;align-items:center;justify-content:center;min-height:100vh;min-height:100dvh}

.maintenance{width:100%;padding:32px 18px}
.maintenance-card{
  max-width:520px;margin-inline:auto;text-align:center;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);
  padding:44px 26px 34px;
  position:relative;overflow:hidden;
}
/* The red margin rule of the notebook, along the top instead of the side */
.maintenance-card::before{
  content:"";position:absolute;inset-block-start:0;inset-inline:0;
  height:4px;background:var(--margin-red);
}
.maintenance-mark{
  font-size:1.5rem;color:var(--ink);
  letter-spacing:.01em;
}

/* Three dots, drawn not written: no icon font to wait for, and nothing to
   translate. They pulse in turn — the only movement on the page, and it is
   what says "someone is working on it" rather than "it is broken". */
.maintenance-icon{display:flex;gap:9px;justify-content:center;margin-block:22px 20px}
.maintenance-icon span{
  width:11px;height:11px;border-radius:50%;background:var(--hi-strong);
  border:1px solid var(--margin-red);
  animation:maintenance-pulse 1.4s ease-in-out infinite;
}
.maintenance-icon span:nth-child(2){animation-delay:.2s}
.maintenance-icon span:nth-child(3){animation-delay:.4s}
@keyframes maintenance-pulse{
  0%,100%{opacity:.35;transform:translateY(0)}
  50%{opacity:1;transform:translateY(-4px)}
}

.maintenance-title{
  font-family:'Aref Ruqaa','Almarai',serif;font-weight:700;
  font-size:1.45rem;line-height:1.7;color:var(--ink-deep);
}
.maintenance-text{
  color:var(--graphite);line-height:2;font-size:1rem;
  margin-block-start:12px;
  white-space:pre-line; /* the admin's line breaks survive into the message */
}
.maintenance-foot{
  margin-block-start:26px;padding-block-start:18px;
  border-block-start:1px solid var(--line);
  color:var(--muted);font-size:.85rem;
}

@media (prefers-reduced-motion:reduce){
  .maintenance-icon span{animation:none;opacity:.8}
}

@media (min-width:769px){
  .maintenance-card{padding:52px 40px 38px}
  .maintenance-title{font-size:1.7rem}
}

/* ───────────────────────── 14. Footer ───────────────────────── */
.footer{
  margin-block-start:auto;
  background:var(--paper-2);border-block-start:1px solid var(--line);
}
.footer-inner{
  max-width:var(--wrap);margin-inline:auto;padding:34px 18px 26px;
  display:flex;justify-content:space-between;gap:26px;flex-wrap:wrap;
}
.footer-name{font-size:1.5rem;color:var(--ink-deep)}
.footer-nav{display:grid;gap:2px;font-size:.94rem}
.footer-nav a{color:var(--graphite);padding-block:8px} /* Touch target ≥ 44px */
.footer-nav a:hover{color:var(--ink)}
.footer-bottom{
  border-block-start:1px solid var(--line);
  text-align:center;font-size:.84rem;color:var(--muted);
  padding-block:14px calc(14px + env(safe-area-inset-bottom, 0px));
  /* Extra side padding on mobile so the floating WhatsApp button does not cover text */
  padding-inline:64px;
}
.footer-bottom>span{display:block}
.footer-bottom>span+span{margin-block-start:4px}
.footer-credit{display:block;font-size:.82rem;color:var(--muted)}
.footer-credit a{display:inline-block;padding-block:6px}

/* ─────────────────────── 15. WhatsApp button ────────────────────── */
.wa-float{
  position:fixed;z-index:50;
  /* env() so the button does not sit under the iPhone home bar or beside the notch */
  inset-block-end:calc(14px + env(safe-area-inset-bottom, 0px));
  inset-inline-start:calc(14px + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));
  width:48px;height:48px;border-radius:50%;overflow:hidden;
  background:var(--wa); /* Shows where the icon is if the image link fails */
  box-shadow:0 4px 16px rgba(0,0,0,.2);
  transition:transform .18s ease;
}
.wa-float:active{transform:scale(.95)}
@media (hover:hover){
  .wa-float:hover{transform:scale(1.07);text-decoration:none}
}
.wa-float img{width:100%;height:100%;display:block;object-fit:cover}

/* ──────────────── 16. From 401px — large phones ────────────────── */
@media (min-width:401px){
  .grade-card{padding:22px 26px 20px}
  .grade-card .g-name{font-size:1.5rem}
  .teacher-card{padding:18px 20px;gap:16px}
  .avatar{width:58px;height:58px;font-size:1.4rem}
  .donate-card{padding:22px}
  .donate-transparency{padding:24px}
  .donate-actions .btn{width:auto}
  .donate-stats{grid-template-columns:repeat(2,1fr)}
}

/* ─────────── 17. From 769px — landscape tablet and desktop ───────────
   Values here match the original design before the Mobile-first reorder
   — do not change them unless the design itself changes. */
@media (min-width:769px){
  :root{--margin-inset:64px;--gap:20px}
  body{line-height:1.85}

  /* Restore buttons and links to original sizes — mouse does not need 44px */
  .btn{min-height:0}
  .crumbs a{display:inline;padding-block:0}
  .footer-nav{gap:8px}
  .footer-nav a{padding-block:0}
  .footer-credit a{display:inline;padding-block:0}
  .person .p-link{padding-block:0}

  .topbar-inner{gap:14px}
  .logo-name{font-size:1.7rem}
  /* A mouse does not need the 44px touch target */
  .theme-toggle{width:40px;height:40px}
  .hero-inner{padding-block:60px 64px;padding-inline:calc(var(--margin-inset) + 46px) 18px}
  .hero-lead{font-size:1.05rem}
  .section{padding-block:44px}
  .section-title{font-size:1.55rem}
  .crumbs{padding-block:18px 4px}

  /* A sheet across the phone becomes a dropdown tucked under the bell.
     Pinned to the start edge, which is the right in RTL — where the bell is. */
  /* Lined up with the content column, which is where the bell is: on a wide
     screen that is the column edge, and on a narrow one it falls back to the
     same 18px the topbar uses for its own padding. */
  .nt-panel{
    inset-inline-start:max(18px, calc(50% - var(--wrap) / 2));
    inset-inline-end:auto;
    width:min(380px, calc(100vw - 36px));
  }

  /* Room for the button beside the text instead of under it */
  .wa-card{flex-direction:row;align-items:center;gap:18px;padding:22px 24px}
  .wa-card-btn{align-self:center;margin-inline-start:auto;flex:0 0 auto}

  .grid-3{grid-template-columns:repeat(auto-fill,minmax(min(268px,100%),1fr))}
  .grid-2{grid-template-columns:repeat(auto-fill,minmax(min(320px,100%),1fr))}

  .profile-inner{padding-block:28px;padding-inline:calc(var(--margin-inset) + 30px) 24px}
  .profile h1{font-size:1.7rem}
  .course-head h1{font-size:1.65rem}
  .doc h1{font-size:1.9rem}
  .progress{min-width:190px}
  .pdf-frame{height:520px}

  .avatar-lg{width:104px;height:104px;font-size:2.4rem}
  .person .avatar{width:200px;height:200px;font-size:4rem}
  .donate-stats{grid-template-columns:repeat(4,1fr)}

  .footer-bottom{padding-inline:18px}
  .wa-float{
    width:52px;height:52px;
    inset-block-end:calc(18px + env(safe-area-inset-bottom, 0px));
    inset-inline-start:calc(18px + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));
  }
}

/* ─────────────────── 18. Reduced motion and print ───────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
}

@media print{
  .topbar,.footer,.wa-float,.install-banner,.lec-actions,.skip-link{display:none}
  body{background:#fff}

  /* Print is always on white paper, so the dark theme is forced back to
     light ink here. Printing it as-is would flood the page with toner and
     come out unreadable. */
  html[data-theme="dark"]{
    color-scheme:light;
    --paper:#fff;--paper-2:#fff;--card:#fff;
    --ink:#24409E;--ink-deep:#182B6B;
    --graphite:#242830;--muted:#4B5563;
    --margin-red:#D8433F;--rule:#DCE4F2;--line:#D5D2C9;
    --hi:#FFE28A;--hi-strong:#FFE28A;
    --hi-ink:var(--ink);--hi-ink-2:var(--margin-red);
    --on-accent:#fff;
    --border-dashed:#C9D3E8;
    --info-bg:#EEF3FF;--info-border:#CBD5EC;--info-text:var(--ink-deep);
    --warn-bg:#FFF3F1;--warn-border:#F0C4BF;--warn-text:#8C2825;
    --shadow:none;--shadow-lift:none;
  }
}

/* ─────────────────── 19. PWA install banner ─────────────────────
   Built in app.js and appended to body, not to #app, so it survives
   route changes. app.js also measures its height into
   --install-banner-h, used below to keep the WhatsApp button clear. */
.install-banner{
  position:fixed;z-index:55;
  inset-inline:10px;
  inset-block-end:calc(10px + env(safe-area-inset-bottom, 0px));
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow-lift);
  padding:14px 16px;
  /* Slides up on transform and opacity only. The global reduced-motion
     rule above kills the transition, so it simply appears in place. */
  opacity:0;transform:translateY(12px);
  transition:opacity .28s ease-out, transform .28s ease-out;
}
.install-banner.is-in{opacity:1;transform:none}

.ib-body{flex:1;min-width:0}
.ib-title{display:block;font-weight:800;color:var(--ink-deep);line-height:1.7}
.ib-steps{
  color:var(--muted);font-size:.88rem;line-height:1.75;
  margin-block-start:4px;overflow-wrap:anywhere;
}

.ib-actions{display:flex;align-items:center;gap:6px;margin-inline-start:auto}
.ib-close{
  flex:0 0 auto;
  width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;
  font-size:1.05rem;line-height:1;color:var(--muted);
  transition:background-color .16s ease, color .16s ease;
}
.ib-close:active{background:var(--paper-2)}
@media (hover:hover){
  .ib-close:hover{background:var(--paper-2);color:var(--graphite)}
}

/* The banner spans the width on phones, so the floating WhatsApp button
   moves above it. Fallback covers the frame before the height is measured. */
body.has-install-banner .wa-float{
  inset-block-end:calc(22px + var(--install-banner-h, 96px) + env(safe-area-inset-bottom, 0px));
}

@media (min-width:769px){
  /* Roomy screens: the banner sits at the inline end, the WhatsApp button
     stays at the inline start, so neither has to move */
  .install-banner{
    inset-inline:auto;
    inset-inline-end:18px;
    inset-block-end:calc(18px + env(safe-area-inset-bottom, 0px));
    max-width:min(560px, calc(100% - 36px));
  }
  body.has-install-banner .wa-float{
    inset-block-end:calc(18px + env(safe-area-inset-bottom, 0px));
  }
}

/* ─────────────────── 20. Dark theme — night notebook ───────────────────
   Same notebook, read at night: the paper goes dark slate, the lines stay
   faint, the red margin rule stays red. Colors only in here — never a size
   or a spacing, so the layout is identical in both themes.

   data-theme is written on <html> by the inline script in index.html before
   the first paint, then kept up to date by initTheme in app.js. */
html[data-theme="dark"]{
  /* Dark scrollbars, dark form controls, dark backdrop behind the PDF frame */
  color-scheme:dark;

  --paper:#11141B;
  --paper-2:#171B23;
  --card:#1C212B;

  /* The blue ink is flipped: --ink-deep was the darkest shade in the light
     theme, so here it becomes the lightest — headings must stay headings. */
  --ink:#93AAF0;
  --ink-deep:#C9D8FF;

  --graphite:#E4E7EE;
  --muted:#9BA4B4;
  --margin-red:#EA6A66;
  --rule:#29303C;
  --line:#2C323D;

  --hi:#4A3C13;         /* Fill: dark, because light text sits on top of it */
  --hi-strong:#E3BE55;  /* Stroke: bright, or the underline disappears */
  --hi-ink:#FFE09A;
  --hi-ink-2:#FFD08C;

  /* --ink is a light blue now, so white text on it lands at 1.9:1 and fails.
     Dark text on it clears 7:1, and it serves every filled surface:
     .btn-ink, .btn-red, .avatar, .lec-num of a watched lecture, .skip-link */
  --on-accent:#10141C;

  --red-hover:#F2827E;  /* Hover goes lighter here, not darker */
  --border-hover:#3D4757;
  --border-dashed:#39424F;

  --info-bg:#1A2036;
  --info-border:#33405F;
  --warn-bg:#2B1A1A;
  --warn-border:#5A2F2C;
  --warn-text:#FFB3AE;

  /* Black instead of blue, and stronger: a pale shadow has no effect on a
     dark surface, so depth comes from a deeper one */
  --shadow:0 1px 2px rgba(0,0,0,.40), 0 8px 24px rgba(0,0,0,.50);
  --shadow-lift:0 2px 4px rgba(0,0,0,.45), 0 14px 34px rgba(0,0,0,.55);
}
