/* data-bot playground default styles — override freely in your own CSS.
   Auto-injected by features/playgrounds/runtime_entry.py on HTML responses.
   Opt out with <html data-pg-defaults="off">.

   Palette/type follow the tvaras.ai + vej.ai design language (see
   frontend/src/index.css): editorial serif headings, neutral sans body,
   mono for labels and figures, square corners, warm paper / near-black
   neutrals, and a single desaturated periwinkle accent.

   Every --pg-* token NAME here is preserved from earlier versions — only
   the values moved. Playgrounds that reference the tokens (or override them
   in their own CSS) keep working untouched. */

/* Brand webfonts, self-hosted. Served by the /fonts mount in server.py, so
   these resolve from a playground page under /pg/<slug>/ too. font-display:
   swap means a cold cache shows the fallback stack rather than blank text. */
@font-face {
  font-family: 'Newsreader';
  src: url('/fonts/newsreader-400.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('/fonts/general-sans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('/fonts/general-sans-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('/fonts/general-sans-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/ibm-plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root, html[data-pg-theme="light"] {
  --pg-bg:           #f7f7f5;
  --pg-app-bg:       #f7f7f5;       /* alias for legacy bundles; matches surface-alt */
  --pg-surface:      #ffffff;
  --pg-surface-alt:  #f0f0ed;
  --pg-border:       #d9d9d6;
  --pg-border-muted: #e9e9e6;
  --pg-fg:           #111113;
  --pg-fg-muted:     #5c5c60;
  --pg-fg-subtle:    #9a9a9e;

  --pg-primary:       #6b7bc4;      /* periwinkle — the single accent */
  --pg-primary-hover: #5867aa;
  --pg-primary-fg:    #ffffff;
  --pg-primary-soft:  #f3f4f8;
  --pg-primary-soft-fg: #49568c;
  --pg-primary-ring:  #cdd2e3;

  --pg-danger:        #b4534b;
  --pg-danger-hover:  #99433c;
  --pg-danger-soft:   #f8eeed;
  --pg-danger-fg:     #99433c;

  --pg-success:       #417a55;
  --pg-success-soft:  #eef4ef;
  --pg-success-fg:    #356245;

  --pg-ring-focus:    rgba(107, 123, 196, 0.45);
  --pg-shadow:        0 1px 2px rgba(17, 17, 19, 0.04), 0 1px 3px rgba(17, 17, 19, 0.06);
  --pg-shadow-lg:     0 10px 30px -10px rgba(17, 17, 19, 0.25);
  /* Square corners, matching both marketing sites. */
  --pg-radius:        0px;
  --pg-radius-lg:     0px;

  --pg-font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --pg-font-sans: 'General Sans', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --pg-font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}

html[data-pg-theme="dark"] {
  --pg-bg:           #0a0a0b;
  --pg-app-bg:       #131315;       /* alias for legacy bundles; matches surface */
  --pg-surface:      #131315;
  --pg-surface-alt:  #1c1c1f;
  --pg-border:       #2a2a2d;
  --pg-border-muted: #1d1d20;
  --pg-fg:           #f2f2f0;
  --pg-fg-muted:     #9a9a9e;
  --pg-fg-subtle:    #5c5c60;

  --pg-primary:       #8b96c2;
  --pg-primary-hover: #aab2d0;
  --pg-primary-fg:    #131315;
  --pg-primary-soft:  rgba(107, 123, 196, 0.14);
  --pg-primary-soft-fg: #aab2d0;
  --pg-primary-ring:  rgba(107, 123, 196, 0.4);

  --pg-danger:        #c9756d;
  --pg-danger-hover:  #d98a82;
  --pg-danger-soft:   rgba(180, 83, 75, 0.16);
  --pg-danger-fg:     #d98a82;

  --pg-success:       #6ba57f;
  --pg-success-soft:  rgba(79, 147, 102, 0.16);
  --pg-success-fg:    #8bbd9b;

  --pg-ring-focus:    rgba(139, 150, 194, 0.45);
  --pg-shadow:        0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
  --pg-shadow-lg:     0 10px 30px -10px rgba(0, 0, 0, 0.6);
}

@media (prefers-color-scheme: dark) {
  html:not([data-pg-theme]) {
    --pg-bg:           #0a0a0b;
    --pg-app-bg:       #131315;
    --pg-surface:      #131315;
    --pg-surface-alt:  #1c1c1f;
    --pg-border:       #2a2a2d;
    --pg-border-muted: #1d1d20;
    --pg-fg:           #f2f2f0;
    --pg-fg-muted:     #9a9a9e;
    --pg-fg-subtle:    #5c5c60;
    --pg-primary:       #8b96c2;
    --pg-primary-hover: #aab2d0;
    --pg-primary-fg:    #131315;
    --pg-primary-soft:  rgba(107, 123, 196, 0.14);
    --pg-primary-soft-fg: #aab2d0;
    --pg-primary-ring:  rgba(107, 123, 196, 0.4);
    --pg-danger:        #c9756d;
    --pg-danger-hover:  #d98a82;
    --pg-danger-soft:   rgba(180, 83, 75, 0.16);
    --pg-danger-fg:     #d98a82;
    --pg-success:       #6ba57f;
    --pg-success-soft:  rgba(79, 147, 102, 0.16);
    --pg-success-fg:    #8bbd9b;
    --pg-ring-focus:    rgba(139, 150, 194, 0.45);
    --pg-shadow:        0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
    --pg-shadow-lg:     0 10px 30px -10px rgba(0, 0, 0, 0.6);
  }
}

/* ── Base elements ── */
html, body {
  background: var(--pg-bg);
  color: var(--pg-fg);
  font-family: var(--pg-font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body { margin: 0; min-height: 100vh; }

/* Headings use the editorial serif, like both marketing sites. A heading
   can opt back into the sans with class="pg-sans" — useful inside dense
   tabular UI where a serif reads as noise. */
h1, h2, h3, h4, h5, h6 {
  color: var(--pg-fg);
  font-family: var(--pg-font-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin: 0 0 0.5em 0;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
h1.pg-sans, h2.pg-sans, h3.pg-sans,
h4.pg-sans, h5.pg-sans, h6.pg-sans { font-family: var(--pg-font-sans); }
h1 { font-size: 1.85rem; }
h2 { font-size: 1.45rem; }
h3 { font-size: 1.2rem; }
h4 { font-size: 1.05rem; }

/* Tabular lining figures everywhere: dashboards are mostly numbers, and
   they should line up column-to-column. */
html { font-feature-settings: "tnum" 1, "lnum" 1; }

p { margin: 0 0 1em 0; color: var(--pg-fg); }
small { color: var(--pg-fg-muted); }
a { color: var(--pg-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

hr { border: 0; height: 1px; background: var(--pg-border); margin: 1.5em 0; }

code, pre, kbd, samp { font-family: var(--pg-font-mono); font-size: 0.9em; }
code {
  background: var(--pg-surface-alt);
  border: 1px solid var(--pg-border-muted);
  border-radius: 4px;
  padding: 1px 5px;
}
pre {
  background: var(--pg-surface-alt);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 12px 14px;
  overflow-x: auto;
  line-height: 1.45;
}
pre code { background: transparent; border: 0; padding: 0; }

/* ── Form elements ── */
button, input, select, textarea { font-family: inherit; font-size: inherit; color: var(--pg-fg); }

button {
  background: var(--pg-surface);
  color: var(--pg-fg);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 6px 12px;
  cursor: pointer;
  font-weight: 500;
  line-height: 1.4;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
button:hover:not(:disabled) { background: var(--pg-surface-alt); }
button:focus-visible { outline: 0; box-shadow: 0 0 0 3px var(--pg-ring-focus); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

button[type="submit"], button.pg-primary {
  background: var(--pg-primary);
  color: var(--pg-primary-fg);
  border-color: transparent;
  box-shadow: var(--pg-shadow);
}
button[type="submit"]:hover:not(:disabled),
button.pg-primary:hover:not(:disabled) { background: var(--pg-primary-hover); }

button.pg-soft {
  background: var(--pg-primary-soft);
  color: var(--pg-primary-soft-fg);
  border: 1px solid var(--pg-primary-ring);
}
button.pg-soft:hover:not(:disabled) { filter: brightness(0.96); }
html[data-pg-theme="dark"] button.pg-soft:hover:not(:disabled) { filter: brightness(1.15); }

button.pg-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--pg-fg-muted);
}
button.pg-ghost:hover:not(:disabled) { background: var(--pg-surface-alt); color: var(--pg-fg); }

button.pg-danger {
  background: var(--pg-danger);
  color: var(--pg-primary-fg);
  border-color: transparent;
  box-shadow: var(--pg-shadow);
}
button.pg-danger:hover:not(:disabled) { background: var(--pg-danger-hover); }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], input[type="url"],
input[type="tel"], input[type="date"], input[type="datetime-local"],
input:not([type]), select, textarea {
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 6px 10px;
  color: var(--pg-fg);
  transition: border-color 120ms ease, box-shadow 120ms ease;
  width: auto;
  max-width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--pg-fg-subtle); }
input:focus, select:focus, textarea:focus {
  outline: 0;
  border-color: var(--pg-primary);
  box-shadow: 0 0 0 3px var(--pg-ring-focus);
}

label { color: var(--pg-fg); font-weight: 500; display: inline-block; }

/* ── Tables ── */
table { border-collapse: collapse; width: 100%; font-size: 0.925em; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--pg-border-muted); }
thead th {
  background: var(--pg-surface-alt);
  color: var(--pg-fg-muted);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.75em;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--pg-border);
}
tbody tr:hover { background: var(--pg-surface-alt); }

/* ── Helper surfaces ── */
.pg-card {
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-lg);
  padding: 16px;
  box-shadow: var(--pg-shadow);
}
.pg-muted { color: var(--pg-fg-muted); }
.pg-subtle { color: var(--pg-fg-subtle); }

/* Ribbon offset — two jobs.
   (1) Normal-flow content is pushed down via body padding so the page
       doesn't start under the ribbon.
   (2) Fixed-positioned user content (sticky top-navs, toolbars) ignores
       body padding — so we publish --pg-ribbon-h that the user can add
       to their own `top` offset: e.g. `top: calc(var(--pg-ribbon-h) + 12px)`.
       Default is 0px; when the ribbon is present, bumps to 48px.
   We also auto-shift a few *very common* fixed-to-top selectors as a
   convenience so pre-existing playgrounds don't need to be edited just
   to work with the ribbon. The user can opt out by not using these
   classes/IDs or setting their own top value (our rule targets
   top:0/top:0px only — an explicit non-zero top wins). */
:root { --pg-ribbon-h: 0px; }
body:has(#__pg_ribbon) { --pg-ribbon-h: 48px; padding-top: 48px; }

/* Convenience shift for common "sticky top bar" patterns. User CSS with
   higher specificity (IDs + `top: 0`) wins only because of inline-style
   declarations or !important. For clean `top: 0` in class-level rules
   ours takes over. If a playground explicitly wants top:0, either (a)
   use !important on their rule or (b) read the --pg-ribbon-h variable
   instead and anchor relative to it. */
body:has(#__pg_ribbon) > header[style*="position:fixed"],
body:has(#__pg_ribbon) > header.fixed,
body:has(#__pg_ribbon) > nav.fixed,
body:has(#__pg_ribbon) #top-nav,
body:has(#__pg_ribbon) .top-nav,
body:has(#__pg_ribbon) .pg-topbar { top: var(--pg-ribbon-h) !important; }

/* ── Anonymize mode ────────────────────────────────────────────────────
 * Single source of truth for anon-mode CSS in playgrounds — applies in
 * both embedded (iframe) and standalone (top-level /pg/<slug>/) contexts.
 *
 * State coordination: the parent app posts {type:'pg-anon', on} to
 * embedded iframes; bootstrap.js toggles body.anon-mode. Standalone
 * pages drive the same class from their own ribbon toggle + localStorage.
 *
 * Targets:
 *   - <img> / <svg> tagged as logo/brand
 *   - any element with [data-anon-chart] / .anon-chart (chart wrappers)
 *   - any element with .anon-num / .anon-target / .anon-brand
 *   - all <td>/<th> in any table (blanket — playground content is
 *     usually a data dashboard, and we can't rely on a remark plugin
 *     to wrap numeric tokens like the chat app does)
 *
 * Headings (h1-h4, thead) and .anon-no-blur subtrees stay sharp so the
 * page remains navigable while sensitive cells are blurred.
 *
 * Hover relaxes to a peek-blur (still unreadable on screenshots).
 */

body.anon-mode .anon-num,
body.anon-mode .anon-target,
body.anon-mode .anon-brand,
body.anon-mode .anon-chart,
body.anon-mode [data-anon-chart],
body.anon-mode img[alt*="logo" i],
body.anon-mode img[alt*="brand" i],
body.anon-mode svg[aria-label*="logo" i],
body.anon-mode table td,
body.anon-mode table th {
  filter: blur(6px);
  transition: filter 120ms ease;
  user-select: none;
}

body.anon-mode .anon-num:hover,
body.anon-mode .anon-target:hover,
body.anon-mode .anon-brand:hover,
body.anon-mode .anon-chart:hover,
body.anon-mode [data-anon-chart]:hover,
body.anon-mode img[alt*="logo" i]:hover,
body.anon-mode img[alt*="brand" i]:hover,
body.anon-mode svg[aria-label*="logo" i]:hover,
body.anon-mode table td:hover,
body.anon-mode table th:hover {
  filter: blur(2px);
}

body.anon-mode .anon-no-blur,
body.anon-mode .anon-no-blur * {
  filter: none !important;
}

body.anon-mode :is(h1, h2, h3, h4, thead) {
  filter: none !important;
}

/* ══════════════════════════════════════════════════════════════════════
 * Small screens
 * ----------------------------------------------------------------------
 * Playgrounds are authored on a desktop and were effectively desktop-only:
 * before this block the whole runtime had a single width-based media query.
 * These are defaults every playground inherits — anything here can still be
 * overridden by the playground's own CSS, which loads afterwards.
 * ══════════════════════════════════════════════════════════════════════ */

/* Never let a playground scroll the page sideways. */
html, body { max-width: 100%; overflow-x: hidden; }

/* Media and embeds shrink instead of forcing a wider page. */
img, svg, video, canvas, iframe { max-width: 100%; }

/* Wide tables scroll inside their own box rather than pushing the layout
   out. `table { width: 100% }` above means a table in a scroll container
   would otherwise crush its columns, so it also takes a min-width here —
   the same trap the admin tables hit. Wrap a table in
   <div class="pg-scroll-x"> to get this explicitly. */
.pg-scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

@media (max-width: 639px) {
  /* Tighter gutters: 24px each side of a 390px screen is a lot of nothing. */
  .pg-ui-container { padding: 14px; }
  .pg-card { padding: 12px; }

  /* Headings scale down so a long dashboard title doesn't take four lines. */
  h1 { font-size: 1.45rem; }
  h2 { font-size: 1.2rem; }
  h3 { font-size: 1.05rem; }

  /* Wide tables: keep readable column widths and scroll sideways, rather
     than crushing columns to fit (a `width: 100%` table in a 390px card
     collapses "Payment method" to one word per line) or widening the page.
     The min-width goes on the TABLE — it can't go on thead/tbody, since
     min-width does not apply to table-row-group boxes — and the scroll goes
     on whichever element directly wraps it, so a playground doesn't have to
     add a wrapper class by hand. Scoped to the known card/container classes
     plus an explicit .pg-scroll-x opt-in; a bare `div:has(> table)` would
     hand scrollbars to arbitrary unrelated wrappers. */
  table { min-width: 544px; }

  .pg-scroll-x,
  .pg-card:has(> table),
  .pg-ui-card:has(> table),
  .pg-ui-panel:has(> table),
  .pg-ui-container:has(> table) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
}

/* Comfortable hit targets on touch devices, without changing the denser
   layout for mouse users. Anchors are excluded on purpose: most links in a
   playground are inline in prose, where a forced box breaks the text. */
/* Sizes are in px, not rem: the playground base sets html{font-size:14px},
   so 2.25rem would resolve to 31.5px and quietly miss the 36px target. */
@media (pointer: coarse) {
  button,
  [role="button"],
  select,
  summary {
    min-height: 36px;
  }
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    min-height: 36px;
  }
  /* iOS Safari zooms the viewport when a focused field is under 16px. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    font-size: max(16px, 1em);
  }
}
