/* ========================================================================
   Cepha.Material — Components
   مكوّنات أساسيّة لا تعرف منصّة. الـflavors تكيّفها لاحقاً.
   ======================================================================== */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--ceph-font);
  background: var(--ceph-bg);
  color: var(--ceph-ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---- تخطيط التطبيق ---- */
.app {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px 16px 80px;
}

/* Head is silent: a mark, a legend of pulsing topology chips,
   a host-link telltale. No prose. The page introduces itself by rhythm. */
.app__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
  padding: 6px 4px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.brand__mark {
  flex: 0 0 auto;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,.05));
  transform-origin: 50% 50%;
  transition: transform .6s cubic-bezier(.2,.8,.2,1);
}
.brand:hover .brand__mark { transform: rotate(8deg); }
.brand__name {
  font-weight: 700;
  font-size: clamp(15px, 2.2vw, 18px);
  letter-spacing: -.005em;
  color: var(--ceph-ink);
  white-space: nowrap;
}

/* Legend = silent topology key. State, not motion. */
.legend {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  padding: 4px 8px;
  background: color-mix(in srgb, var(--ceph-surface) 75%, transparent);
  border: 1px solid var(--ceph-line);
  border-radius: 999px;
  backdrop-filter: blur(6px);
}

.legend__link {
  width: 14px; height: 1px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--ceph-ink) 32%, transparent),
    color-mix(in srgb, var(--ceph-ink) 14%, transparent));
  border-radius: 1px;
}
.legend__sep {
  width: 1px; height: 14px;
  background: var(--ceph-line);
  margin: 0 4px;
}

/* Chips are state markers — filled disc when active, hollow when not. */
.ceph-badge {
  position: relative;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  display: inline-grid;
  place-items: center;
  isolation: isolate;
  cursor: help;
  --ring: var(--ceph-line);
  --core: var(--ceph-ink-soft);
  transition: transform .2s ease;
}
.ceph-badge:hover { transform: scale(1.12); }
.ceph-badge > i {
  width: 7px; height: 7px;
  border-radius: 999px;
  background: var(--core);
  display: block;
  transition: background .25s ease, box-shadow .25s ease;
}
.ceph-badge::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 1px solid var(--ring);
  pointer-events: none;
}

.ceph-badge--core   { --ring: var(--ceph-core-500);   --core: var(--ceph-core-500); }
.ceph-badge--mantle { --ring: var(--ceph-mantle-500); --core: var(--ceph-mantle-500); }
.ceph-badge--crust  { --ring: var(--ceph-crust-500);  --core: var(--ceph-crust-500); }
.ceph-badge--host   { --ring: var(--ceph-line);       --core: var(--ceph-ink-soft); }

/* Host link is the ONE living indicator. Single tiny heartbeat — and only
   when actually online. Offline = hollow ring, fully still.            */
.ceph-badge--host[data-online="1"] { --ring: #2bb673; --core: #2bb673; }
.ceph-badge--host[data-online="1"] > i {
  box-shadow: 0 0 0 0 rgba(43,182,115,.55);
  animation: host-beat 2.4s ease-out infinite;
}
.ceph-badge--host[data-online="0"] > i {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--ceph-ink-soft);
}

@keyframes host-beat {
  0%, 60%, 100% { box-shadow: 0 0 0 0   rgba(43,182,115,.55); }
  20%           { box-shadow: 0 0 0 5px rgba(43,182,115,0);   }
}

/* ---- شبكة البطاقات ---- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}

/* ---- البطاقة الجوهر · Card ---- */
.ceph-card,
.slot {
  position: relative;
  background: var(--ceph-surface);
  border-radius: var(--ceph-radius-md);
  padding: 16px;
  min-height: 180px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px solid var(--ceph-line);
  transition: transform var(--ceph-motion-mantle),
              box-shadow var(--ceph-motion-mantle);
  overflow: hidden;
}

.ceph-card::before,
.slot::before {
  /* شريط طبقة على الحافّة العلويّة — جيولوجيا مرئيّة */
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: linear-gradient(90deg, transparent, currentColor, transparent);
  opacity: .55;
}

/* — طبولوجيا: قشرة (browser) — */
.slot[data-topology="browser"] {
  color: var(--ceph-crust-500);
  box-shadow: var(--ceph-elev-crust);
  z-index: var(--ceph-z-crust);
}
.slot[data-topology="browser"]:hover {
  box-shadow: 0 4px 12px rgba(30,95,116,.18);
  transform: translateY(-1px);
}

/* — طبولوجيا: وشاح (hybrid) — */
.slot[data-topology="hybrid"] {
  color: var(--ceph-mantle-500);
  box-shadow: var(--ceph-elev-mantle);
  z-index: var(--ceph-z-mantle);
  background: linear-gradient(180deg, var(--ceph-surface) 0%, var(--ceph-mantle-50) 100%);
}
.slot[data-topology="hybrid"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 18px rgba(201,123,60,.28),
              0 4px 8px rgba(201,123,60,.18),
              inset 0 0 0 1px rgba(244,162,97,.30);
}

/* — طبولوجيا: لبّ (server) — */
.slot[data-topology="server"] {
  color: var(--ceph-core-500);
  box-shadow: var(--ceph-elev-core);
  z-index: var(--ceph-z-core);
  background:
    radial-gradient(ellipse at 50% 0%, var(--ceph-core-50) 0%, var(--ceph-surface) 60%);
}
.slot[data-topology="server"]:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 36px rgba(110,31,47,.40),
              0 8px 14px rgba(110,31,47,.22),
              inset 0 0 28px rgba(200,75,49,.16);
}

/* Placeholder is silent and still. The skeleton hairline only appears
   if mounting actually takes >250ms — on localhost it never does, so
   the page boots straight into resolved cards with no "loading…" feel. */
.slot__placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--ceph-ink-soft);
  height: 100%;
}
.slot__glyph {
  font-size: 30px;
  line-height: 1;
}
.slot__title {
  font-style: normal;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -.005em;
  color: var(--ceph-ink);
}
.slot__skeleton {
  width: 56px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, currentColor 65%, transparent) 50%,
    transparent 100%);
  background-size: 200% 100%;
  background-position: 200% 0;
  opacity: 0;
  animation: skeleton-late 1.6s linear 280ms infinite;
}

@keyframes skeleton-late {
  0%   { opacity: 0;  background-position: 200% 0; }
  20%  { opacity: .9; }
  80%  { opacity: .9; }
  100% { opacity: 0;  background-position: -200% 0; }
}

/* Choreographed entry — each card lands on M3 emphasized-decelerate,
   staggered 70ms by DOM order. Sub-pixel float at rest.            */
.slot {
  animation: slot-enter .62s cubic-bezier(.05,.7,.1,1) both;
  animation-delay: calc(var(--slot-i, 0) * 70ms);
}
.slot:nth-child(1) { --slot-i: 0; }
.slot:nth-child(2) { --slot-i: 1; }
.slot:nth-child(3) { --slot-i: 2; }
.slot:nth-child(4) { --slot-i: 3; }
.slot:nth-child(5) { --slot-i: 4; }
.slot:nth-child(6) { --slot-i: 5; }
.slot:nth-child(7) { --slot-i: 6; }
.slot:nth-child(8) { --slot-i: 7; }
.slot:nth-child(n+9) { --slot-i: 8; }

@keyframes slot-enter {
  0%   { opacity: 0; transform: translateY(8px) scale(.985); filter: blur(2px); }
  60%  { opacity: 1; filter: blur(0); }
  100% { opacity: 1; transform: translateY(0)   scale(1);    filter: blur(0); }
}

@media (prefers-reduced-motion: reduce) {
  .slot, .slot__skeleton,
  .ceph-badge--host[data-online="1"] > i { animation: none !important; }
}

/* ---- ceph-btn host element (no visuals; vendor component fills it) ----
 * Strict-sized host so the M3/Apple/MAUI delegate cannot grow on click. */
ceph-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  height: 40px;
  min-width: 96px;
  max-width: 280px;
  contain: layout paint;
  isolation: isolate;
  position: relative;
  border-radius: var(--ceph-radius-btn);
}
ceph-btn[disabled] { opacity: .55; pointer-events: none; }
ceph-btn[label="−"], ceph-btn[label="+"] { min-width: 44px; width: 44px; padding: 0; }

/* M3 tone bridge — push our geo-topology palette into Material 3 tokens
 * via the documented --md-sys-color-* + container-shape/height surface. */
ceph-btn md-filled-button {
  display: inline-flex;
  width: 100%;
  height: 100%;
  --md-sys-color-primary: var(--ceph-mantle-500);
  --md-sys-color-on-primary: var(--ceph-mantle-on);
  --md-filled-button-container-shape: var(--ceph-radius-btn);
  --md-filled-button-container-height: 40px;
  --md-filled-button-label-text-font: var(--ceph-font);
  --md-filled-button-label-text-weight: 600;
  --md-filled-button-label-text-size: 14px;
  --md-filled-button-label-text-tracking: -0.005em;
}
ceph-btn md-filled-button[data-tone="crust"] {
  --md-sys-color-primary: var(--ceph-crust-500);
  --md-sys-color-on-primary: var(--ceph-crust-on);
}
ceph-btn md-filled-button[data-tone="core"] {
  --md-sys-color-primary: var(--ceph-core-500);
  --md-sys-color-on-primary: var(--ceph-core-on);
}

/* Apple-system HTML fallback — restrained, not a pill. */
.apple-system-button {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Arabic", system-ui;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 0 20px;
  border: 0;
  border-radius: var(--ceph-radius-btn);
  background: var(--ceph-mantle-500);
  color: var(--ceph-mantle-on);
  cursor: pointer;
  transition: background .18s cubic-bezier(.4,0,.2,1),
              opacity .18s cubic-bezier(.4,0,.2,1),
              filter .18s cubic-bezier(.4,0,.2,1);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  will-change: background, opacity;
}
.apple-system-button[data-tone="crust"] { background: var(--ceph-crust-500); color: var(--ceph-crust-on); }
.apple-system-button[data-tone="core"]  { background: var(--ceph-core-500);  color: var(--ceph-core-on); }
.apple-system-button:hover  { filter: brightness(1.06); }
.apple-system-button:active { filter: brightness(.94); opacity: .92; }
.apple-system-button[data-mode="offline-host"]::after {
  content: " ⚡"; opacity: .6; font-size: .9em; font-weight: 400;
}
.apple-system-button:focus-visible {
  outline: 2px solid var(--ceph-crust-500);
  outline-offset: 2px;
}

/* ---- نصّ داخل البطاقة ---- */
.ceph-card__title {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--ceph-ink);
}

.ceph-card__body {
  margin: 0;
  font-size: 13px;
  color: var(--ceph-ink-soft);
  flex: 1;
}

.ceph-card__meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  color: var(--ceph-ink-soft);
  font-family: var(--ceph-font-mono);
}

.ceph-card__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* ---- إضافات: header/icon/input/chip/counter/clock ---- */
.ceph-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.ceph-card__icon { font-size: 22px; }
.ceph-card__title { font-weight: 700; flex: 1; color: var(--ceph-ink); }

.ceph-input {
  flex: 1;
  min-width: 0;
  padding: 8px 12px;
  border: 1px solid var(--ceph-line);
  border-radius: var(--ceph-radius-sm);
  background: var(--ceph-surface);
  color: var(--ceph-ink);
  font: inherit;
  font-size: 13px;
}
.ceph-input:focus {
  outline: 2px solid var(--ceph-crust-300);
  outline-offset: 0;
  border-color: var(--ceph-crust-500);
}

.ceph-chip {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--ceph-surface-2);
  color: var(--ceph-ink-soft);
  border: 1px solid var(--ceph-line);
}
.ceph-chip.ok  { background: var(--ceph-crust-50);  color: var(--ceph-crust-700); border-color: var(--ceph-crust-100); }
.ceph-chip.err { background: var(--ceph-core-50);   color: var(--ceph-core-700);  border-color: var(--ceph-core-100);  }

.counter {
  font-family: var(--ceph-font-mono);
  font-weight: 700;
  font-size: 18px;
  min-width: 2.5ch;
  text-align: center;
  color: var(--ceph-ink);
}

.clock {
  font-family: var(--ceph-font-mono);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ceph-crust-700);
  text-align: center;
  padding: 10px;
  background: var(--ceph-crust-50);
  border-radius: var(--ceph-radius-sm);
}

/* ripple القديم (للتوافق مع applyDirective) */
.ripple {
  position: absolute;
  border-radius: 50%;
  transform: scale(0);
  pointer-events: none;
  background: currentColor;
  opacity: .28;
  animation: ceph-ripple-anim 320ms ease-out forwards;
}

/* Cupertino fade على .tapped */
[data-flavor="ios-native"] .tapped { opacity: .55; }

/* ---- LCD pulse — broadcast animation shared by every <ceph-btn> ----
 * Implemented as a ::after outline ON THE HOST ceph-btn (not the inner
 * vendor element). This way the button bounds NEVER change on click. */
ceph-btn::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: calc(var(--ceph-radius-btn) + 2px);
  border: 2px solid transparent;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease-out;
}
ceph-btn.lcd-pulse::after {
  border-color: var(--ceph-lcd-pulse-color, var(--ceph-mantle-500));
  animation: ceph-lcd-pulse var(--ceph-lcd-pulse-ms, 320ms) ease-out;
}
@keyframes ceph-lcd-pulse {
  0%   { opacity: 0; transform: scale(.985); }
  35%  { opacity: .8; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.02); }
}
@media (prefers-reduced-motion: reduce) {
  ceph-btn.lcd-pulse::after { animation: none; opacity: 0; }
}

/* ─── طبولوجيا الأمان · Safety topology ───────────────────────────────────
 * Active when the LCD broadcast reports the server is gone. Browser-topology
 * cards survive (they never needed the server). Server/hybrid slots are
 * sealed: visually marked, network-incapable, and explicitly labelled so the
 * viewer can see that no untrusted call was made. This is a defined area —
 * a "topology of trust" — not a generic offline state. */

[data-topology="safety"] body {
  background:
    linear-gradient(180deg, var(--ceph-bg) 0%, color-mix(in srgb, var(--ceph-crust-50) 18%, var(--ceph-bg)) 100%);
}

[data-topology="safety"] #card-grid {
  position: relative;
  padding: 18px;
  border: 1px dashed color-mix(in srgb, var(--ceph-crust-500) 55%, transparent);
  border-radius: var(--ceph-radius-lg);
  background: color-mix(in srgb, var(--ceph-crust-50) 35%, transparent);
  transition: background .35s ease, border-color .35s ease;
}
[data-topology="safety"] #card-grid::before {
  content: "🛡️ منطقة آمنة · لا نداءات للخادم من هذا الإطار";
  position: absolute;
  top: -12px; right: 16px;
  background: var(--ceph-surface);
  color: var(--ceph-crust-700);
  border: 1px solid color-mix(in srgb, var(--ceph-crust-500) 50%, transparent);
  border-radius: 999px;
  padding: 3px 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .005em;
}

/* Sealed cards in safety topology behave like plasma screens —
   the contained gas glows, drifts, and almost leaks until the server returns.
   Strong semantic: the card isn't "broken", it's pressurized & waiting. */
.slot[data-sealed="1"] {
  position: relative;
  pointer-events: none;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--ceph-radius-md);
  filter: saturate(.7) brightness(.94);
}

/* Plasma chamber: animated gradient gas behind the card content. */
.slot[data-sealed="1"]::before {
  content: "";
  position: absolute; inset: 0;
  z-index: 2;
  border-radius: inherit;
  background:
    radial-gradient(120% 80% at 18% 22%, rgba(120,200,255,.55), transparent 55%),
    radial-gradient(110% 90% at 82% 78%, rgba(255,120,200,.45), transparent 60%),
    radial-gradient(140% 100% at 50% 110%, rgba(160,255,220,.40), transparent 65%),
    linear-gradient(135deg,
      color-mix(in srgb, var(--ceph-surface-2) 86%, transparent),
      color-mix(in srgb, var(--ceph-surface) 92%, transparent));
  background-size: 180% 180%, 200% 200%, 220% 220%, 100% 100%;
  background-position: 0% 0%, 100% 100%, 50% 100%, 0 0;
  mix-blend-mode: screen;
  animation: plasma-drift 11s ease-in-out infinite alternate;
  box-shadow:
    inset 0 0 24px rgba(120,200,255,.35),
    inset 0 0 60px rgba(255,120,200,.18);
  filter: blur(.3px) saturate(1.15);
}

/* Seal label + the "leaking" rim — gas pressing the boundary. */
.slot[data-sealed="1"]::after {
  content: "⊘ مختومة · بانتظار عودة الخادم";
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  z-index: 3;
  color: color-mix(in srgb, var(--ceph-ink) 75%, transparent);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .01em;
  border-radius: inherit;
  border: 1px dashed color-mix(in srgb, #78c8ff 55%, var(--ceph-line));
  background:
    radial-gradient(60% 40% at 50% 50%, rgba(255,255,255,.55), transparent 70%);
  backdrop-filter: blur(1.5px);
  text-shadow: 0 1px 0 rgba(255,255,255,.6);
  animation: plasma-leak 3.6s ease-in-out infinite;
}

@keyframes plasma-drift {
  0%   { background-position: 0% 0%,   100% 100%, 50% 100%, 0 0; transform: scale(1); }
  50%  { background-position: 100% 30%, 0% 70%,   30% 40%,  0 0; transform: scale(1.015); }
  100% { background-position: 40% 100%, 60% 0%,   80% 20%,  0 0; transform: scale(1); }
}

@keyframes plasma-leak {
  0%, 100% {
    box-shadow:
      inset 0 0 0 1px rgba(120,200,255,.0),
      0 0 0 0 rgba(120,200,255,.0);
  }
  45% {
    box-shadow:
      inset 0 0 18px rgba(120,200,255,.35),
      0 0 12px 2px rgba(120,200,255,.22);
  }
  70% {
    box-shadow:
      inset 0 0 22px rgba(255,120,200,.30),
      0 0 16px 3px rgba(255,120,200,.18);
  }
}

@media (prefers-reduced-motion: reduce) {
  .slot[data-sealed="1"]::before,
  .slot[data-sealed="1"]::after { animation: none; }
}

/* Surviving browser cards get a faint trust ring while we're in safety. */
[data-topology="safety"] .slot[data-topology="browser"] {
  box-shadow:
    0 1px 2px rgba(30,95,116,.12),
    0 0 0 1px color-mix(in srgb, var(--ceph-crust-500) 40%, transparent);
}

/* Safety banner — discreet, top of viewport, not modal. */
.safety-banner {
  position: fixed;
  top: 12px; left: 12px; right: 12px;
  z-index: 9999;
  display: flex; gap: 12px; align-items: center;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--ceph-crust-50) 92%, var(--ceph-surface));
  border: 1px solid color-mix(in srgb, var(--ceph-crust-500) 35%, transparent);
  border-radius: 14px;
  box-shadow: 0 6px 22px rgba(30,95,116,.18);
  font-size: 13px;
  color: var(--ceph-crust-900);
  animation: safety-slide-in .28s cubic-bezier(.4,0,.2,1);
}
.safety-banner[hidden] { display: none; }
.safety-banner__icon { font-size: 20px; line-height: 1; }
.safety-banner__body { flex: 1; display: flex; flex-direction: column; gap: 2px; line-height: 1.35; }
.safety-banner__body strong { font-size: 14px; color: var(--ceph-crust-700); }
.safety-banner__body span { color: var(--ceph-ink-soft); font-size: 12px; }
.safety-banner__pwa {
  color: var(--ceph-crust-700);
  text-decoration: none;
  font-weight: 600;
  font-size: 12px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--ceph-crust-500) 40%, transparent);
  white-space: nowrap;
  transition: background .15s, color .15s;
}
.safety-banner__pwa:hover {
  background: var(--ceph-crust-500);
  color: var(--ceph-crust-on);
}
@keyframes safety-slide-in {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* Online → ensure surviving DOM doesn't keep safety chrome. */
[data-topology="web"] #card-grid {
  border: none; background: transparent; padding: 0;
}
[data-topology="web"] #card-grid::before { display: none; }
