/*
  BULGAR WEBGADGETS — the panel.

  Same visual language as the Revive and Console apps on bulgar.mobi: graphite
  ground, a faint grid that reads as texture rather than content, monospace for
  anything the machine said, and colour used only to mean something. Nothing is
  loaded from off this domain - no font, no icon set, no analytics - so the page
  is the same in a plane seat as at a desk.

  Built mobile-first at 390px. Every control clears 44px, and the shell pads
  itself out of the notch with env(safe-area-inset-*).
*/

:root {
  --ink: #e9ebee;
  --ink-2: #b6bcc5;
  --ink-3: #939aa4;
  --ink-4: #7d848e;
  --line: #262b33;
  --line-strong: #343a44;
  --surface: rgba(22, 25, 30, 0.72);
  --go: #49dd9d;
  --gold: #d8b063;
  --warn: #f2bc60;
  --bad: #f4907f;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  color-scheme: dark;
}

* { box-sizing: border-box; }

body.wg {
  margin: 0;
  min-height: 100dvh;
  background:
    radial-gradient(120% 55% at 50% -5%, rgba(73, 221, 157, 0.11), transparent 60%),
    linear-gradient(rgba(73, 221, 157, 0.045) 1px, transparent 1px) 0 0 / 100% 34px,
    linear-gradient(90deg, rgba(73, 221, 157, 0.045) 1px, transparent 1px) 0 0 / 34px 100%,
    #0b0d10;
  color: var(--ink);
  font-family: var(--mono);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 6px; }

.wg-wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 22px) 16px calc(env(safe-area-inset-bottom) + 48px);
}

/* ------------------------------- header ------------------------------- */

.wg-head { display: flex; align-items: center; gap: 12px; margin: 0 0 6px; }
.wg-dot {
  width: 11px; height: 11px; border-radius: 50%; flex: none; background: var(--go);
  box-shadow: 0 0 0 4px rgba(73, 221, 157, 0.12), 0 0 18px rgba(73, 221, 157, 0.7);
}
.wg-head h1 { margin: 0; font-size: 19px; letter-spacing: 0.2em; font-weight: 700; }
.wg-head p { margin: 2px 0 0; font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }

/* The one paragraph that explains the whole page, because forty demos called
   "otp v7" explain nothing by themselves. */
.wg-lede {
  margin: 16px 0 0; font-size: 12.5px; line-height: 1.65; color: var(--ink-3);
  max-width: 62ch;
}
.wg-lede b { color: var(--ink-2); }

.wg-stats { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
.wg-stat {
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  padding: 8px 12px; font-size: 11px; letter-spacing: 0.06em; color: var(--ink-4);
}
.wg-stat b { display: block; font-size: 19px; letter-spacing: 0; color: var(--ink); }
.wg-stat[data-tone="go"] b { color: var(--go); }
.wg-stat[data-tone="warn"] b { color: var(--warn); }

/* ------------------------------ controls ------------------------------ */

.wg-controls {
  position: sticky; top: 0; z-index: 5;
  margin: 22px -16px 0; padding: 12px 16px;
  background: linear-gradient(#0b0d10 72%, rgba(11, 13, 16, 0));
}
.wg-search {
  width: 100%; min-height: 46px; padding: 12px 14px;
  border: 1px solid var(--line-strong); border-radius: 12px;
  background: #14171c; color: var(--ink);
  font-family: inherit; font-size: 16px; /* 16px or Safari zooms the page in */
  -webkit-appearance: none;
}
.wg-search::placeholder { color: var(--ink-4); }
.wg-search:focus { outline: none; border-color: var(--go); box-shadow: 0 0 0 3px rgba(73, 221, 157, 0.15); }

.wg-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0; }
.wg-chip {
  min-height: 34px; padding: 0 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; background: #14171c;
  color: var(--ink-3); font-family: inherit; font-size: 11.5px;
  letter-spacing: 0.08em; text-transform: uppercase;
  transition: color 140ms var(--ease), border-color 140ms var(--ease);
}
.wg-chip:hover { color: var(--ink); }
.wg-chip[aria-pressed="true"] { color: #0b0d10; background: var(--go); border-color: var(--go); font-weight: 700; }

/* -------------------------------- grid -------------------------------- */

.wg-grid {
  display: grid; gap: 10px; margin: 14px 0 0;
  grid-template-columns: 1fr;
}
@media (min-width: 680px) { .wg-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .wg-grid { grid-template-columns: 1fr 1fr 1fr; } }

.wg-card {
  display: flex; flex-direction: column; gap: 10px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface); padding: 14px;
  transition: border-color 160ms var(--ease), transform 90ms var(--ease);
}
.wg-card:hover { border-color: var(--line-strong); }
.wg-card[hidden] { display: none; }

.wg-card-top { display: flex; align-items: flex-start; gap: 10px; }
.wg-num {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  background: #14171c; border: 1px solid var(--line);
  font-size: 11px; color: var(--ink-4);
}
.wg-card h2 { margin: 0; font-size: 14.5px; letter-spacing: 0.03em; line-height: 1.35; }
.wg-kind { font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }

.wg-badges { display: flex; flex-wrap: wrap; gap: 5px; }
.wg-badge {
  font-size: 10.5px; letter-spacing: 0.04em; color: var(--ink-4);
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px;
}

.wg-note { font-size: 11px; color: var(--ink-4); line-height: 1.5; }
.wg-note[data-tone="warn"] { color: var(--warn); }

.wg-acts { display: flex; gap: 6px; margin-top: auto; }
.wg-btn {
  flex: 1; min-height: 44px; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: 10px; background: #1b1f25;
  color: var(--ink-2); font-family: inherit; font-size: 12px;
  font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  display: grid; place-items: center;
  transition: color 140ms var(--ease), border-color 140ms var(--ease), background 140ms var(--ease);
}
.wg-btn:hover { color: var(--ink); border-color: var(--ink-4); }
.wg-btn[data-tone="run"] { color: var(--go); border-color: rgba(73, 221, 157, 0.4); }
.wg-btn[data-tone="run"]:hover { background: rgba(73, 221, 157, 0.12); border-color: var(--go); }
.wg-btn[disabled] { opacity: 0.4; cursor: not-allowed; }

.wg-empty { margin: 30px 0; text-align: center; color: var(--ink-4); font-size: 13px; }

/* ------------------------------- viewer ------------------------------- */
/* The gadget runs in an iframe, full screen. Isolation is the point: most of
   these style the page itself, and a demo that sets a body background must not
   be able to reach the panel. */

.wg-modal { position: fixed; inset: 0; z-index: 50; display: none; flex-direction: column; background: #0b0d10; }
.wg-modal[open] { display: flex; }
.wg-modal-bar {
  display: flex; align-items: center; gap: 10px;
  padding: calc(env(safe-area-inset-top) + 10px) 12px 10px;
  border-bottom: 1px solid var(--line); background: #101318;
}
.wg-modal-bar b { font-size: 13px; letter-spacing: 0.05em; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wg-modal-bar a, .wg-modal-bar button {
  min-height: 40px; padding: 0 12px; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: 9px; background: #1b1f25;
  color: var(--ink-2); font-family: inherit; font-size: 11.5px;
  letter-spacing: 0.08em; text-transform: uppercase; display: grid; place-items: center;
}
.wg-modal-bar a:hover, .wg-modal-bar button:hover { color: var(--ink); border-color: var(--ink-4); }
.wg-modal-id { flex: 1; min-width: 0; }
.wg-modal-id b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wg-modal-id small { display: block; font-size: 10.5px; letter-spacing: 0.1em; color: var(--ink-4); white-space: nowrap; }

/* At 390px the bar carries six controls and the title was crushed to "v2 …"
   while the counter wrapped onto two lines. The controls give up their padding
   first, because a shorter button is still a button and a title with no room
   is not a title. */
@media (max-width: 480px) {
  .wg-modal-bar { gap: 6px; padding-left: 8px; padding-right: 8px; }
  .wg-modal-bar a, .wg-modal-bar button { padding: 0 9px; font-size: 10.5px; letter-spacing: 0.04em; }
  #modal-prev, #modal-next { min-width: 38px; padding: 0 8px; font-size: 18px; }
  .wg-modal-bar b { font-size: 12px; }
}
#modal-prev, #modal-next { font-size: 20px; line-height: 1; padding: 0 13px; min-width: 44px; }

/* The stage holds the gadget and the two strips you can swipe on. */
.wg-stage { position: relative; flex: 1; display: flex; overflow: hidden; }
.wg-modal iframe { flex: 1; width: 100%; border: 0; background: #fff; }

/*
   THE SWIPE STRIPS.

   A thumb's width down each side, above the frame. They are transparent and
   they are the ONLY part of the gadget area that belongs to this page: an
   iframe keeps every touch that lands on it, so a swipe across the middle is
   the gadget's, not ours. Covering the whole gadget to catch it would also
   swallow the taps meant for the thing you are trying out.

   `touch-action: pan-y` lets a vertical drag still scroll while a horizontal
   one is ours to interpret.
*/
.wg-swipe {
  position: absolute; top: 0; bottom: 0; width: 34px; z-index: 2;
  touch-action: pan-y; background: transparent;
}
.wg-swipe[data-edge='left'] { left: 0; }
.wg-swipe[data-edge='right'] { right: 0; }
@media (min-width: 900px) { .wg-swipe { width: 56px; } }

/* Said once, briefly, the first three times only. */
.wg-hint {
  position: absolute; left: 50%; bottom: calc(env(safe-area-inset-bottom) + 18px);
  transform: translateX(-50%);
  margin: 0; padding: 9px 15px; z-index: 3; pointer-events: none;
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: rgba(11, 13, 16, 0.9); color: var(--ink-2);
  font-size: 11.5px; letter-spacing: 0.06em; white-space: nowrap;
  opacity: 0; transition: opacity 260ms var(--ease);
}
.wg-hint[data-show] { opacity: 1; }

/* A short slide in the direction of travel, so a change is visible rather than
   just a different picture appearing. */
@keyframes wg-in-r { from { transform: translateX(9%); opacity: 0.25; } to { transform: none; opacity: 1; } }
@keyframes wg-in-l { from { transform: translateX(-9%); opacity: 0.25; } to { transform: none; opacity: 1; } }
.wg-modal iframe.in-r { animation: wg-in-r 220ms var(--ease); }
.wg-modal iframe.in-l { animation: wg-in-l 220ms var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .wg-modal iframe.in-r, .wg-modal iframe.in-l { animation: none; }
}

/* ---------------------------- source viewer --------------------------- */

.wg-bar {
  display: flex; align-items: center; gap: 12px;
  padding: calc(env(safe-area-inset-top) + 12px) 16px 12px;
  border-bottom: 1px solid var(--line); background: #101318;
  position: sticky; top: 0; z-index: 5;
}
.wg-bar div { flex: 1; min-width: 0; }
.wg-bar b { display: block; font-size: 14px; letter-spacing: 0.04em; }
.wg-bar small { display: block; font-size: 11px; color: var(--ink-4); }
.wg-back, .wg-run {
  min-height: 40px; padding: 0 12px; display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: 9px; background: #1b1f25;
  font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
}
.wg-run { color: var(--go); border-color: rgba(73, 221, 157, 0.4); }

.wg-src { max-width: 1180px; margin: 0 auto; padding: 16px 16px 60px; }
.wg-files { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 18px; }
.wg-files a {
  font-size: 11px; color: var(--ink-3); border: 1px solid var(--line);
  border-radius: 7px; padding: 5px 9px; background: #14171c;
}
.wg-files a:hover { color: var(--ink); border-color: var(--ink-4); }
.wg-files span { color: var(--ink-4); margin-left: 7px; }

.wg-code section { margin: 0 0 16px; }
.wg-code h2 {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  margin: 0; font-size: 12.5px; letter-spacing: 0.05em; color: var(--gold);
  border: 1px solid var(--line); border-bottom: 0; border-radius: 10px 10px 0 0;
  background: #14171c; padding: 9px 12px;
}
.wg-code h2 em { font-style: normal; font-size: 11px; color: var(--ink-4); }
.wg-code pre {
  margin: 0; padding: 12px; overflow-x: auto;
  border: 1px solid var(--line); border-radius: 0 0 10px 10px;
  background: #0f1216; color: var(--ink-2);
  font-size: 12px; line-height: 1.55; tab-size: 2;
}
.wg-skip {
  margin: 0; padding: 12px; font-size: 11.5px; color: var(--ink-4);
  border: 1px solid var(--line); border-radius: 0 0 10px 10px; background: #0f1216;
}

@media (prefers-reduced-motion: reduce) {
  .wg-card, .wg-btn, .wg-chip { transition: none; }
}
