/* PRESENCE KIT — SHELL. Six slots: header / nav / frame / footer / sheet / toast.
   Same two laws as components.css: semantic tokens only, logical properties only.

   TWO FRAME MODES, one shell around both:
     data-frame="site"  bounded editorial     — content 1100px inside a 1440 outer
     data-frame="app"   single fluid column   — 760px, phone-first, narrow on
                                                laptop BY DESIGN (§11 chassis:
                                                the master-detail split is
                                                retired; detail navigates).
   A page declares its mode on <html>; nothing else changes between them. */

/* ================================ shell ================================ */

.shell {
  min-block-size: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
}

/* The one place a width is decided. Every band/section inside either frame
   uses `.frame` for its inline bound so the two never disagree. */
.frame {
  inline-size: 100%;
  margin-inline: auto;
  padding-inline: var(--space-5);
}
[data-frame="site"] .frame { max-inline-size: var(--frame-site); }
[data-frame="app"]  .frame { max-inline-size: var(--frame-app); }
.frame--wide { max-inline-size: var(--frame-site-outer); }
.frame--flush { padding-inline: 0; }

/* =============================== header ================================
   TWO ROWS. Row 1 is identity (mark + name + the locale/theme controls);
   row 2 is the nav rail. They are separate rows because a rail that shares a
   line with a wordmark cannot scroll to its own edge on a phone — the chips
   run under the logo and the last one is unreachable. */

.hdr {
  position: sticky;
  inset-block-start: 0;
  z-index: 40;
  background: var(--surface);
  border-block-end: 1px solid var(--border);
  /* A sticky translucent header over Arabic text smears it; keep it opaque. */
}
.hdr__brand {
  min-block-size: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-2);
}
/* A MARK IS SIZED BY ITS BOUNDING BOX, NOT BY ITS HEIGHT. Brand marks are not
   all landscape: Tondro's is 1226x1829 (portrait), so a 30px block-size made
   it a ~20px-wide speck beside the tools while a landscape mark filled the
   row — one rule, two very different logos. Sizing the BOX and letting
   object-fit:contain letterbox inside it gives every mark the same optical
   weight whatever its aspect ratio. */
/* object-position has no logical keyword, so the mark is CENTERED in its box
   rather than edge-anchored: centering mirrors for free and costs a few px of
   optical slack, where `left center` would need a [dir=rtl] override. */
.hdr__mark {
  block-size: 40px;
  inline-size: 112px;
  object-fit: contain;
  object-position: center;
  flex: 0 0 auto;
  display: block;
}
/* Wordmark fallback for a company with no usable SVG (rukn, isnad today). */
.hdr__wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--step-1);
  color: var(--ink-heading);
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
}
.hdr__wordmark small {
  display: block;
  font-family: var(--font-arabic-display);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-muted);
  letter-spacing: 0;
}
.hdr__spacer { flex: 1 1 auto; }
.hdr__tools  { display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; }

/* ============================== nav rail ===============================
   "RAILS, NOT PILLS" (§13 nav-tree). ONE horizontally-scrollable
   NON-WRAPPING row of 36px chips with 8px rhythm. Nothing collapses, nothing
   hides behind a dropdown — siblings stay one thumb-swipe away, and the
   active chip scrolls itself into view (kit.js). Dropdowns are the worst
   primary-nav pattern measured; this is the behavior customers already know. */

.rail {
  display: flex;
  gap: var(--space-2);                 /* 8px rhythm */
  align-items: center;
  min-block-size: var(--rail-h);
  padding-block: var(--space-2);
  overflow-x: auto;
  overflow-y: hidden;
  flex-wrap: nowrap;                   /* the law: a rail NEVER wraps */
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: inline proximity;
  /* Bleed to the frame edge so the last chip can reach it, then re-pad. */
  scroll-padding-inline: var(--space-5);
  overscroll-behavior-inline: contain;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; }
.rail--sub { min-block-size: 44px; border-block-start: 1px solid var(--border); }

/* Breadcrumb: at 3+ levels, two visible rails max + ONE tappable line above
   (orientation and UP only — never a third rail). */
.crumbs {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  font-size: var(--step--1);
  color: var(--ink-muted);
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.crumbs::-webkit-scrollbar { display: none; }
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--ink); }
/* THE SEPARATOR IS A BORDER TRIANGLE — NO GLYPH, NO ROTATION.
   Three failed shapes, each instructive: a `>` GLYPH points back the way you
   came in RTL; a two-border CHEVRON mirrors its borders but `rotate()` turns
   in SCREEN space, which `direction` does not touch, so the same 45deg drew
   `>` in English and `^` in Arabic (caught in the tondro-ar crumbs shot — the
   borders had mirrored, the rotation had not); and a per-script rotation
   needs the `[dir=rtl]` override this kit refuses.
   The classic CSS triangle has NO rotation to go stale: a solid
   `border-inline-start` against transparent block borders points toward
   inline-end by construction, so it mirrors with the writing mode for free. */
.crumbs__sep {
  inline-size: 0;
  block-size: 0;
  border-block-start: 4px solid transparent;
  border-block-end: 4px solid transparent;
  border-inline-start: 5px solid currentColor;
  opacity: 0.45;
  flex: 0 0 auto;
}

/* =============================== content =============================== */

.main { flex: 1 1 auto; }
[data-frame="app"] .main { padding-block: var(--space-5); }

/* =============================== footer ================================ */

.ftr {
  margin-block-start: var(--space-section);
  padding-block: var(--space-7) var(--space-5);
  background: var(--surface-2);
  border-block-start: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: var(--step--1);
}
.ftr__top {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  margin-block-end: var(--space-6);
}
.ftr__brand { display: flex; flex-direction: column; gap: var(--space-3); }
.ftr__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border);
}
.ftr a { color: var(--ink); text-decoration: none; }
.ftr a:hover { text-decoration: underline; }

/* ================================ sheet ================================
   ONE component, two placements: bottom sheet on a phone (thumb reach),
   centered dialog on a laptop. Same markup, same open/close. */

.sheet-scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: 60;
  display: none;
}
.sheet-scrim[data-open="true"] { display: block; }

.sheet {
  position: fixed;
  z-index: 61;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
  display: none;
  flex-direction: column;
  max-block-size: 88svh;
  overflow: auto;
  /* Phone: bottom sheet, full-bleed inline, rounded top only. */
  inset-inline: 0;
  inset-block-end: 0;
  border-start-start-radius: var(--radius-sheet);
  border-start-end-radius: var(--radius-sheet);
  padding: var(--space-5);
  padding-block-end: max(var(--space-5), env(safe-area-inset-bottom));
  animation: sheet-up var(--dur) var(--ease);
}
.sheet[data-open="true"] { display: flex; }
@keyframes sheet-up { from { transform: translateY(12%); opacity: 0.6; } }

@media (min-width: 720px) {
  .sheet {
    inset-inline: 50%;
    inset-block: auto;
    inset-block-start: 50%;
    translate: -50% -50%;
    /* `translate:-50%` is physical-axis-free (X is X in both scripts), but the
       inline centering above already mirrors; this only re-centers the box. */
    inline-size: min(560px, 92vw);
    border-radius: var(--radius-card);
    animation: sheet-in var(--dur) var(--ease);
  }
  @keyframes sheet-in { from { opacity: 0; scale: 0.97; } }
}

.sheet__grip {
  inline-size: 40px; block-size: 4px; border-radius: var(--radius-pill);
  background: var(--border-strong); margin-inline: auto;
  margin-block-end: var(--space-4); flex: 0 0 auto;
}
@media (min-width: 720px) { .sheet__grip { display: none; } }
.sheet__head {
  display: flex; align-items: center; gap: var(--space-3);
  margin-block-end: var(--space-4);
}
.sheet__title { font-size: var(--step-2); margin: 0; flex: 1 1 auto; }
.sheet__foot { margin-block-start: var(--space-5); display: flex;
               gap: var(--space-3); flex-wrap: wrap; }

/* ================================ toast ================================
   Bottom-centered, above the safe area. Not inline-start-anchored: a toast is
   a notification, not content, and centering makes it script-agnostic. */

.toasts {
  position: fixed;
  inset-block-end: max(var(--space-5), env(safe-area-inset-bottom));
  inset-inline: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  pointer-events: none;
  padding-inline: var(--space-5);
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-inline-size: min(440px, 100%);
  padding-block: var(--space-3);
  padding-inline: var(--space-5);
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--surface);
  box-shadow: var(--shadow-card);
  font-size: var(--step--1);
  font-weight: 600;
  animation: toast-in var(--dur) var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
.toast--ok  { background: var(--status-ok);  color: var(--surface); }
.toast--err { background: var(--status-err); color: var(--surface); }

/* ============================ skip + a11y ============================== */

.skip {
  position: absolute;
  inset-inline-start: var(--space-4);
  inset-block-start: -100px;
  z-index: 99;
  padding: var(--space-3) var(--space-4);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius-input);
  text-decoration: none;
}
.skip:focus { inset-block-start: var(--space-3); }
.u-sr {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
