/* Layout and components. No colour literals -- every one comes from themes.css.

   Direction: the whole sheet uses logical properties (inline-start/end, margin-
   inline, padding-block) so Arabic RTL and English LTR share one set of rules.
   Anything that needs a real mirror -- the progress fill, the stage arrows --
   is noted where it happens. */

@font-face {
  font-family: 'Readex Pro';
  src: url('assets/ui/ReadexPro.woff2') format('woff2');
  font-weight: 160 700;
  font-display: swap;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Readex Pro', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 16px;
  line-height: 1.65;
  font-weight: 400;
}

/* Interface numbers stay Western in both languages (plan section 5); the
   preview is where Arabic-Indic digits belong. */
.num, table, .stat, input[type="number"] { font-variant-numeric: tabular-nums; }

:where(a) { color: var(--accent); text-underline-offset: .2em; }

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

.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;
}

.skip-link {
  position: absolute; inset-block-start: -100px; inset-inline-start: 1rem;
  background: var(--accent); color: var(--accent-ink);
  padding: .6rem 1rem; border-radius: 0 0 var(--radius) var(--radius); z-index: 20;
}
.skip-link:focus { inset-block-start: 0; }

/* ------------------------------------------------------------------ shell */

.wrap { max-width: 62rem; margin-inline: auto; padding-inline: clamp(1rem, 4vw, 2.5rem); }

header.top {
  position: sticky; inset-block-start: 0; z-index: 10;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--line);
}
header.top .wrap {
  display: flex; align-items: center; gap: var(--gap);
  padding-block: .85rem; min-height: 60px;
}
.brand { font-weight: 600; font-size: 1rem; margin-inline-end: auto; letter-spacing: -.01em; }
.brand span { color: var(--ink-faint); font-weight: 400; }

.ghost {
  appearance: none; background: transparent; color: var(--ink-muted);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .4rem .75rem; font: inherit; font-size: .85rem; cursor: pointer;
}
.ghost:hover { border-color: var(--line-strong); color: var(--ink); }

.intro { padding-block: clamp(2rem, 6vw, 3.5rem) 1.5rem; max-width: var(--measure); }
.intro h1 {
  font-size: clamp(1.6rem, 4vw, 2.4rem); line-height: 1.25;
  margin: 0 0 .6rem; font-weight: 600; letter-spacing: -.02em;
}
.intro p { margin: 0; color: var(--ink-muted); }

.privacy-line {
  display: flex; align-items: flex-start; gap: .55rem;
  margin-block-start: 1.1rem; padding: .7rem .9rem;
  background: var(--accent-soft); border-radius: var(--radius);
  font-size: .875rem; color: var(--ink);
}
.privacy-line svg { flex: none; margin-block-start: .25rem; }
.privacy-line a { white-space: nowrap; }

/* ----------------------------------------------------------------- stages */

.stage {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg-raised); margin-block-end: .75rem; overflow: hidden;
}
.stage[data-state="active"] { border-color: var(--line-strong); box-shadow: var(--shadow); }
.stage[data-state="locked"] { opacity: .5; }
.stage[data-state="locked"] .stage-body { display: none; }
.stage[data-state="done"] .stage-body { display: none; }

.stage-head {
  display: flex; align-items: center; gap: .75rem; width: 100%;
  padding: 1rem 1.25rem; background: none; border: 0; font: inherit;
  color: inherit; text-align: start;
}
.stage[data-state="done"] .stage-head { cursor: pointer; }
.stage[data-state="locked"] .stage-head,
.stage[data-state="active"] .stage-head { cursor: default; }

.stage-num {
  flex: none; inline-size: 1.75rem; block-size: 1.75rem; border-radius: 50%;
  display: grid; place-items: center; font-size: .8rem; font-weight: 600;
  background: var(--bg-inset); color: var(--ink-muted);
}
.stage[data-state="active"] .stage-num { background: var(--accent); color: var(--accent-ink); }
.stage[data-state="done"] .stage-num { background: var(--ok-soft); color: var(--ok); }

.stage-title { font-weight: 600; font-size: .98rem; }
.stage-summary {
  margin-inline-start: auto; color: var(--ink-faint); font-size: .85rem;
  text-align: end; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-inline-size: 55%;
}
.stage[data-state="done"] .stage-summary::after {
  content: '↩'; margin-inline-start: .5rem; color: var(--accent);
}
/* The glyph is directional, so it must be mirrored for LTR. */
:root[dir="ltr"] .stage[data-state="done"] .stage-summary::after { content: '↪'; }

.stage-body { padding: 0 1.25rem 1.35rem; }

/* --------------------------------------------------------------- dropzone */

.drop {
  border: 2px dashed var(--line-strong); border-radius: var(--radius-lg);
  padding: clamp(2rem, 8vw, 3.5rem) 1.5rem; text-align: center;
  background: var(--bg-sunken); transition: background .15s, border-color .15s;
}
.drop.over { border-color: var(--accent); background: var(--accent-soft); }
.drop p { margin: .35rem 0; color: var(--ink-muted); font-size: .9rem; }
.drop strong { display: block; font-size: 1.05rem; color: var(--ink); margin-block-end: .35rem; }

.btn {
  appearance: none; border: 0; border-radius: var(--radius);
  background: var(--accent); color: var(--accent-ink);
  padding: .7rem 1.4rem; font: inherit; font-weight: 600; cursor: pointer;
}
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .45; cursor: not-allowed; filter: none; }
.btn.secondary { background: var(--bg-inset); color: var(--ink); }
.btn.big { inline-size: 100%; padding-block: .95rem; font-size: 1.05rem; }
.btn.danger { background: var(--bad-soft); color: var(--bad); }

/* ------------------------------------------------------------------ table */

.tbl { inline-size: 100%; border-collapse: collapse; font-size: .875rem; }
.tbl th, .tbl td {
  padding: .55rem .6rem; text-align: start; border-block-end: 1px solid var(--line);
  white-space: nowrap;
}
.tbl th { color: var(--ink-faint); font-weight: 500; font-size: .78rem; }
.tbl td.name { white-space: normal; font-weight: 500; }
.tbl tr:last-child td { border-block-end: 0; }
.scroll-x { overflow-x: auto; margin-inline: -.6rem; padding-inline: .6rem; }

.pill {
  display: inline-block; padding: .1rem .5rem; border-radius: 99px;
  font-size: .75rem; font-weight: 500; background: var(--bg-inset); color: var(--ink-muted);
}
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad { background: var(--bad-soft); color: var(--bad); }

/* ------------------------------------------------------------------ notes */

.note {
  display: flex; gap: .6rem; padding: .8rem .95rem; border-radius: var(--radius);
  font-size: .875rem; margin-block: .75rem; border: 1px solid transparent;
}
.note b { font-weight: 600; }
.note.info { background: var(--bg-sunken); border-color: var(--line); }
.note.ok   { background: var(--ok-soft);   color: var(--ok); }
.note.warn { background: var(--warn-soft); color: var(--warn); }
.note.bad  { background: var(--bad-soft);  color: var(--bad); }
.note p { margin: 0 0 .35rem; }
.note p:last-child { margin-block-end: 0; }

/* ---------------------------------------------------------------- options */

.cards { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }

.card {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .9rem 1rem; background: var(--bg); display: block; cursor: pointer;
}
.card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.card:has(input:disabled) { opacity: .5; cursor: not-allowed; }
.card-head { display: flex; align-items: center; gap: .6rem; }
.card-head input { inline-size: 1.05rem; block-size: 1.05rem; accent-color: var(--accent); flex: none; }
.card-head b { font-weight: 600; font-size: .92rem; }
.card small { display: block; color: var(--ink-faint); font-size: .8rem; margin-block-start: .4rem; }
.card .demo {
  margin-block-start: .6rem; padding: .5rem .65rem; background: var(--bg-inset);
  border-radius: 6px; font-size: 1.05rem; display: flex; align-items: center;
  gap: .5rem; justify-content: center;
}
.card .demo .arrow { color: var(--ink-faint); font-size: .85rem; }

.field { margin-block: 1rem; }
.field label { display: block; font-size: .85rem; font-weight: 500; margin-block-end: .35rem; }
.field small { display: block; color: var(--ink-faint); font-size: .8rem; margin-block-start: .3rem; }
input[type="text"], input[type="number"], select {
  inline-size: 100%; padding: .55rem .7rem; font: inherit; font-size: .92rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--bg); color: var(--ink);
}
.row { display: flex; gap: .75rem; flex-wrap: wrap; }
.row > * { flex: 1 1 12rem; }

/* --------------------------------------------------------------- progress */

.bar {
  block-size: .5rem; background: var(--bg-inset); border-radius: 99px;
  overflow: hidden; margin-block: .6rem;
}
/* The fill is a plain child, so in an RTL container it grows from the right
   without any extra rule -- that is the point of not using `left`. */
.bar > i { display: block; block-size: 100%; background: var(--accent); inline-size: 0; transition: inline-size .2s; }
.progress-line { display: flex; justify-content: space-between; font-size: .85rem; color: var(--ink-muted); }

/* ---------------------------------------------------------------- preview */

.preview-shell { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.preview-input {
  inline-size: 100%; border: 0; border-block-end: 1px solid var(--line);
  padding: 1rem 1.1rem; font-size: 1.9rem; line-height: 1.5; background: var(--bg);
  color: var(--ink); resize: vertical; min-block-size: 5.5rem; font-family: inherit;
}
.preview-input:focus { outline-offset: -2px; }
.preview-controls {
  display: flex; align-items: center; gap: .85rem; padding: .7rem 1.1rem;
  background: var(--bg-sunken); flex-wrap: wrap;
}
.preview-controls label { font-size: .82rem; color: var(--ink-muted); white-space: nowrap; }
input[type="range"] { flex: 1 1 8rem; accent-color: var(--accent); min-inline-size: 6rem; }
.samples { display: flex; gap: .4rem; flex-wrap: wrap; margin-block-start: .7rem; }
.samples button {
  appearance: none; background: var(--bg-inset); border: 1px solid var(--line);
  color: var(--ink-muted); border-radius: 99px; padding: .3rem .7rem;
  font: inherit; font-size: .8rem; cursor: pointer;
}
.samples button:hover { color: var(--ink); border-color: var(--line-strong); }

.weights-panel { margin-block-start: 1.25rem; }
.weights-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: .75rem; margin-block-start: .6rem;
}
/* The point of this panel is one comparison per currency, so the two weights
   are a pair that cannot be split by a wrap. */
.weight-pair {
  display: grid; grid-template-columns: 1fr 1fr; gap: .5rem;
  border: 1px solid var(--line); border-radius: var(--radius); padding: .5rem;
  background: var(--bg-sunken);
}
.weight-pair .caption {
  grid-column: 1 / -1; text-align: center; font-size: .78rem;
  color: var(--ink-faint); order: 1;
}
.weight-pair .weight-cell { border: 0; background: var(--bg); }
.weight-cell {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem .5rem .55rem; text-align: center; background: var(--bg-sunken);
}
.weight-cell .glyph { font-size: 3.2rem; line-height: 1.1; display: block; }
.weight-cell .label { font-size: .75rem; color: var(--ink-faint); margin-block-start: .4rem; }

/* ---------------------------------------------------------------- reports */

.report { display: grid; gap: .5rem; margin-block-start: .8rem; }
.report-row {
  display: flex; align-items: center; gap: .7rem; padding: .6rem .85rem;
  border-radius: var(--radius); border: 1px solid var(--line); font-size: .875rem;
  background: var(--bg);
}
.report-row.pass { border-inline-start: 3px solid var(--ok); }
.report-row.fail { border-inline-start: 3px solid var(--bad); background: var(--bad-soft); }
.report-row.note { border-inline-start: 3px solid var(--line-strong); }
.report-row .who { font-weight: 500; }
.report-row .what { color: var(--ink-muted); margin-inline-start: auto; text-align: end; }

/* --------------------------------------------------------------- download */

.downloads { display: grid; gap: .5rem; }
.dl {
  display: flex; align-items: center; gap: .75rem; padding: .8rem 1rem;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg);
  font: inherit; color: var(--ink); cursor: pointer; text-align: start; inline-size: 100%;
}
.dl:hover { border-color: var(--accent); }
.dl .kind { font-weight: 600; font-size: .92rem; }
.dl .meta { color: var(--ink-faint); font-size: .8rem; }
.dl .size { margin-inline-start: auto; color: var(--ink-faint); font-size: .82rem; }

.os-tabs { display: flex; gap: .35rem; margin-block: 1rem .6rem; flex-wrap: wrap; }
.os-tabs button {
  appearance: none; background: transparent; border: 1px solid var(--line);
  border-radius: 99px; padding: .35rem .85rem; font: inherit; font-size: .82rem;
  color: var(--ink-muted); cursor: pointer;
}
.os-tabs button[aria-selected="true"] {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
}
.steps { margin: 0; padding-inline-start: 1.2rem; color: var(--ink-muted); font-size: .9rem; }
.steps li { margin-block-end: .35rem; }

footer.foot {
  margin-block-start: 3rem; padding-block: 2rem 3rem;
  border-block-start: 1px solid var(--line); color: var(--ink-faint); font-size: .85rem;
}
footer.foot a { color: var(--ink-muted); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* Engine status: the visitor is downloading ~7MB of runtime before anything
   can happen, so say so rather than showing a dead page. */
.engine-status {
  margin-block: .7rem 0; font-size: .82rem; color: var(--ink-faint);
  display: flex; align-items: center; gap: .45rem;
}
.engine-status::before {
  content: ''; inline-size: .5rem; block-size: .5rem; border-radius: 50%;
  background: var(--line-strong); flex: none;
}
.engine-status[data-state="ready"]::before { background: var(--ok); }
.engine-status[data-state="failed"]::before { background: var(--bad); }
.engine-status[data-state="failed"] { color: var(--bad); }

.recap {
  margin: 0 0 .9rem; font-size: .85rem; color: var(--ink-muted);
  padding: .5rem .75rem; background: var(--bg-sunken); border-radius: var(--radius);
}

/* A value like "233 KB" is two LTR runs; dropped into an RTL paragraph the
   bidi algorithm orders them right-to-left and it reads "KB 233". Isolating
   the span AND forcing its direction keeps the pair together and in order,
   while the cell itself stays start-aligned for the page's direction. */
.ltr { direction: ltr; unicode-bidi: isolate; display: inline-block; }

/* U+20C1..20C4 are too new for any system font to have, so printing the
   codepoint on the option cards shows tofu or, worse, an unrelated fallback
   glyph. The official artwork is painted as a mask instead: real shape, real
   colour in both themes, and no dependency on what the visitor has installed.
   The built font is the only place the actual codepoints get rendered. */
.sym {
  display: inline-block; block-size: 1em; background: currentColor;
  -webkit-mask: var(--sym) center / contain no-repeat;
  mask: var(--sym) center / contain no-repeat;
  vertical-align: -.1em;
}

/* ------------------------------------------------- static prose pages */

/* Long-form prose is written twice, once per language, rather than being
   assembled from JSON keys: paragraphs need to be edited as paragraphs. The
   root's lang attribute picks which copy is shown. */
:root[lang="ar"] .lx-en, :root[lang="en"] .lx-ar { display: none; }

.prose { max-width: var(--measure); padding-block: 2rem 1rem; }
.prose h1 { font-size: clamp(1.4rem, 3.5vw, 2rem); line-height: 1.3; margin: 0 0 1rem; font-weight: 600; }
.prose h2 { font-size: 1.05rem; margin: 2rem 0 .5rem; font-weight: 600; }
.prose h3 { font-size: .95rem; margin: 1.4rem 0 .35rem; font-weight: 600; color: var(--ink-muted); }
.prose p, .prose li { color: var(--ink-muted); }
.prose li { margin-block-end: .4rem; }
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85em;
  background: var(--bg-inset); padding: .1em .35em; border-radius: 4px;
  direction: ltr; unicode-bidi: isolate; display: inline-block;
}
.prose ol, .prose ul { padding-inline-start: 1.3rem; }
.prose .back { display: inline-block; margin-block-end: 1.5rem; font-size: .875rem; }
.prose table { inline-size: 100%; border-collapse: collapse; font-size: .875rem; margin-block: .75rem; }
.prose th, .prose td { padding: .5rem .6rem; border-block-end: 1px solid var(--line); text-align: start; }
.prose th { color: var(--ink-faint); font-weight: 500; font-size: .8rem; }

@media (max-width: 30rem) {
  /* Keep the name, drop the tagline -- it wraps the header to two lines. */
  .brand span { display: none; }
  .stage-summary { max-inline-size: 42%; }
  .preview-input { font-size: 1.5rem; }
}

/* The rename override: a deliberate opt-out of a licence safeguard, so it is
   styled as a quiet secondary control rather than a peer of the field above. */
.override {
  display: flex; gap: .55rem; align-items: flex-start;
  margin-block-start: .8rem; padding: .65rem .8rem;
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
  cursor: pointer;
}
.override input { margin-block-start: .25rem; accent-color: var(--accent); flex: none; }
.override b { font-size: .87rem; font-weight: 600; }
.override small { display: block; color: var(--ink-faint); font-size: .8rem; margin-block-start: .25rem; }
.override:has(input:checked) { border-style: solid; border-color: var(--warn); background: var(--warn-soft); }
.override:has(input:checked) small { color: var(--ink-muted); }

/* ------------------------------------------------------------ about block */

.about {
  padding: 1.1rem 1.25rem; border: 1px solid var(--line);
  border-radius: var(--radius-lg); background: var(--bg-raised);
  margin-block-end: 1.5rem;
}
.about h2 { font-size: .95rem; margin: 0 0 .5rem; font-weight: 600; color: var(--ink); }
.about p { margin: 0 0 .4rem; }
.about p:last-child { margin-block-end: 0; }
.project-links { display: flex; gap: .5rem; flex-wrap: wrap; margin-block-start: .75rem !important; }
.project-links a {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .35rem .75rem; border: 1px solid var(--line);
  border-radius: 99px; font-size: .82rem; text-decoration: none;
  color: var(--ink-muted); background: var(--bg);
}
.project-links a:hover { border-color: var(--accent); color: var(--accent); }

/* ------------------------------------------- custom currency + the skill */

.custom-form {
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 1rem; margin-block: .75rem; background: var(--bg-sunken);
}
.custom-form h4 { margin: 0 0 .2rem; font-size: .92rem; font-weight: 600; }
.custom-form > p { margin: 0 0 .8rem; color: var(--ink-faint); font-size: .82rem; }
.custom-actions { display: flex; gap: .5rem; margin-block-start: .9rem; flex-wrap: wrap; }

.svg-drop {
  display: flex; align-items: center; gap: .75rem; padding: .7rem .85rem;
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
  background: var(--bg); cursor: pointer;
}
.svg-drop.has-file { border-style: solid; border-color: var(--ok); }
.svg-drop .preview {
  inline-size: 2.2rem; block-size: 2.2rem; flex: none;
  display: grid; place-items: center; background: var(--bg-inset); border-radius: 6px;
}
.svg-drop .preview img { max-inline-size: 100%; max-block-size: 100%; }
.svg-drop .label { font-size: .85rem; }
.svg-drop .label small { display: block; color: var(--ink-faint); font-size: .78rem; }

.custom-list { display: grid; gap: .5rem; margin-block: .5rem; }
.custom-item {
  display: flex; align-items: center; gap: .75rem; padding: .6rem .85rem;
  border: 1px solid var(--accent); border-radius: var(--radius);
  background: var(--accent-soft); font-size: .875rem;
}
.custom-item .preview {
  inline-size: 1.8rem; block-size: 1.8rem; flex: none; display: grid; place-items: center;
}
.custom-item .preview img { max-inline-size: 100%; max-block-size: 100%; }
.custom-item .meta { color: var(--ink-muted); font-size: .8rem; }
.custom-item button {
  margin-inline-start: auto; appearance: none; background: none; border: 0;
  color: var(--bad); font: inherit; font-size: .82rem; cursor: pointer;
  text-decoration: underline; padding: 0;
}

.skill-block {
  margin-block-start: 2.5rem; padding: 1.35rem 1.5rem;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg-sunken);
}
.skill-block h2 { font-size: 1.02rem; margin: 0 0 .5rem; font-weight: 600; }
.skill-block h3 { font-size: .88rem; margin: 1.1rem 0 .3rem; font-weight: 600; }
.skill-block p { margin: 0 0 .6rem; color: var(--ink-muted); font-size: .9rem; }
.skill-block .ghost { margin-inline-start: .5rem; text-decoration: none; display: inline-block; }
.skill-install code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82em;
  background: var(--bg-inset); padding: .12em .4em; border-radius: 4px;
  direction: ltr; unicode-bidi: isolate; display: inline-block;
}
#skill-status:empty { display: none; }

/* Code blocks are always left-to-right, whatever the page direction: a shell
   command reads the same in both languages, and an Arabic placeholder inside
   one must not drag the whole line around. */
.prose pre, .skill-block pre {
  direction: ltr; unicode-bidi: isolate; text-align: start;
  background: var(--bg-inset); padding: .8rem 1rem; border-radius: var(--radius);
  overflow-x: auto; font-size: .85rem;
}
.prose pre code { background: none; padding: 0; }
