/* ── Soft UI — opt-in presentation layer ─────────────────────────────────
   Ported from the p_dash (FinCast) aesthetic: system font, large radii,
   soft glass cards, pill controls, hover lifts. Every color resolves
   through the Trellis theme tokens in base.html (--ink-*, --ash-*,
   --garnet, --gold, semantic status vars), so light/dark both work and
   the palette stays Trellis.

   Usage: add class "soft" to a page's top-level container(s) inside
   {% block main %} (including any fixed modal roots that sit outside the
   main container), and load this file from {% block head_scripts %}:
     <link rel="stylesheet" href="/static/soft.css">
   Page {% block styles %} rules come later in the cascade and win. */

.soft {
  /* typography */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui, sans-serif;
  --mono: 'DM Mono', monospace;          /* data accents only: SKUs, times, money */
  --r: 16px;

  /* surfaces (auto re-theme via Trellis tokens) */
  --card: var(--ink-2);
  --card2: var(--ink-3);
  --pop: var(--ink-2);
  --hair: var(--ink-4);
  --hair2: var(--ink-5);
  --sep: var(--ink-4);

  /* text */
  --label: var(--ash-light);
  --label2: var(--ash);
  --label3: var(--ash-dim);

  /* accent = garnet, always */
  --accent: var(--garnet);
  --accent-fill: var(--garnet);
  --accent-soft: rgba(109, 46, 70, 0.10);
  --gold-soft: rgba(176, 141, 60, 0.14);

  /* light-literal materials (dark overrides below) */
  --wash: rgba(61, 27, 46, 0.05);
  --wash2: rgba(61, 27, 46, 0.09);
  --track: rgba(61, 27, 46, 0.08);
  --glassbg: rgba(255, 255, 255, 0.62);
  --glasspop: rgba(255, 255, 255, 0.86);
  --glass-inset: inset 0 1px 0 rgba(255, 255, 255, 0.85), inset 0 -1px 0 rgba(42, 24, 32, 0.08);
  --glass-drop: 0 12px 34px rgba(61, 27, 46, 0.10);
  --edge-hi: rgba(255, 255, 255, 1);
  --edge-lo: rgba(61, 27, 46, 0.22);
  --carve-in: inset 0 2px 3px rgba(61, 27, 46, 0.10), inset 0 -1px 0 rgba(255, 255, 255, 0.9);
  --btn-lift: 0 5px 14px rgba(61, 27, 46, 0.16);
  --row-lift: 0 3px 10px rgba(61, 27, 46, 0.11);
  --soft-shadow: 0 12px 34px rgba(61, 27, 46, 0.13);
  --scrimbg: rgba(42, 24, 32, 0.35);
  --ambient:
    radial-gradient(60% 45% at 12% 0%, rgba(109, 46, 70, 0.07), transparent 60%),
    radial-gradient(50% 40% at 88% 12%, rgba(176, 141, 60, 0.06), transparent 60%),
    radial-gradient(55% 40% at 50% 105%, rgba(109, 46, 70, 0.05), transparent 60%);

  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
  color: var(--label);
}
html[data-theme="dark"] .soft {
  --accent: var(--garnet-light);
  --accent-soft: rgba(168, 36, 63, 0.18);
  --gold-soft: rgba(201, 169, 97, 0.15);
  --wash: rgba(255, 255, 255, 0.05);
  --wash2: rgba(255, 255, 255, 0.09);
  --track: rgba(255, 255, 255, 0.08);
  --glassbg: rgba(26, 24, 22, 0.55);
  --glasspop: rgba(30, 27, 25, 0.86);
  --glass-inset: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 -1px 0 rgba(0, 0, 0, 0.42);
  --glass-drop: 0 12px 34px rgba(0, 0, 0, 0.38);
  --edge-hi: rgba(255, 255, 255, 0.20);
  --edge-lo: rgba(0, 0, 0, 0.75);
  --carve-in: inset 0 2px 3px rgba(0, 0, 0, 0.45), inset 0 -1px 0 rgba(255, 255, 255, 0.06);
  --btn-lift: 0 5px 14px rgba(0, 0, 0, 0.45);
  --row-lift: 0 3px 10px rgba(0, 0, 0, 0.35);
  --soft-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  --scrimbg: rgba(8, 8, 8, 0.55);
  --ambient:
    radial-gradient(60% 45% at 12% 0%, rgba(139, 26, 47, 0.10), transparent 60%),
    radial-gradient(50% 40% at 88% 12%, rgba(201, 169, 97, 0.06), transparent 60%),
    radial-gradient(55% 40% at 50% 105%, rgba(139, 26, 47, 0.07), transparent 60%);
}

/* ── ambient backdrop: only the page's primary container draws it ── */
.soft.soft-main { position: relative; isolation: isolate; }
.soft.soft-main::before {
  content: ""; position: fixed; inset: 0; z-index: -1;
  background: var(--ambient); pointer-events: none;
}

.soft button:focus-visible,
.soft a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── labels ── */
.soft .eyebrow {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--label2);
}
.soft .field-label {
  display: block; font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--label3); margin-bottom: 5px;
}

/* ── glass card ── */
.soft .card {
  position: relative; border-radius: var(--r); padding: 14px;
  border: 1px solid var(--hair);
  background: var(--glassbg);
  backdrop-filter: blur(28px) saturate(1.8);
  -webkit-backdrop-filter: blur(28px) saturate(1.8);
  box-shadow: var(--glass-inset), var(--glass-drop);
  display: flex; flex-direction: column; gap: 11px;
  transition: background-color .35s ease, box-shadow .35s ease;
}
.soft .card > .c-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }

/* carved chamfer rim for cards and faceted controls (opt in via .facet) */
.soft .card::before, .soft .facet::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  padding: 1.4px; pointer-events: none; z-index: 2;
  background: linear-gradient(148deg, var(--edge-hi), transparent 38%, transparent 62%, var(--edge-lo));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.soft .facet { position: relative; }

/* ── hero number ── */
.soft .hero-num {
  font-size: 34px; font-weight: 640; letter-spacing: -0.02em; line-height: 1.05;
  font-variant-numeric: normal;
}
.soft .hero-sub { font-size: 13px; color: var(--label2); }
.soft .hero-sub strong { color: var(--label); font-weight: 600; }

/* ── metric chips ── */
.soft .metricgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
.soft .metric-chip {
  position: relative; background: var(--card2); border-radius: 12px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.soft .metric-chip .mname { font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--label3); }
.soft .metric-chip .mval { font-size: 18px; font-weight: 620; letter-spacing: -0.01em; color: var(--label); }
.soft .metric-chip .msub { font-size: 11px; color: var(--label3); }

/* ── pills ── */
.soft .pill {
  display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600;
  letter-spacing: 0.03em; padding: 3px 10px; border-radius: 100px; white-space: nowrap;
}
.soft .pill-neutral { color: var(--label2); background: var(--track); }
.soft .pill-accent  { color: var(--accent); background: var(--accent-soft); }
.soft .pill-gold    { color: var(--gold-dark); background: var(--gold-soft); }
.soft .pill-success { color: var(--success-fg); background: var(--success-bg); }
.soft .pill-warn    { color: var(--warn-fg); background: var(--warn-bg); }
.soft .pill-danger  { color: var(--danger-fg); background: var(--danger-bg); }
.soft .pill-info    { color: var(--info-fg); background: var(--info-bg); }
html[data-theme="dark"] .soft .pill-gold { color: var(--gold); }

/* status badges (Trellis-wide names, soft skin) */
.soft .status-badge {
  display: inline-flex; align-items: center; font-size: 10px; font-weight: 650;
  letter-spacing: 0.05em; text-transform: uppercase; padding: 2px 9px; border-radius: 100px;
}
.soft .status-draft     { background: var(--track); color: var(--label3); }
.soft .status-scheduled { background: var(--info-bg); color: var(--info-fg); }
.soft .status-live      { background: var(--success-bg); color: var(--success-fg); }
.soft .status-completed { background: var(--track); color: var(--label2); }
.soft .status-canceled  { background: var(--danger-bg); color: var(--danger-fg); }
.soft .status-test      { background: var(--warn-bg); color: var(--warn-fg); }
.soft .status-loop      { background: var(--info-bg); color: var(--info-fg); }
.soft .status-daily     { background: var(--gold-soft); color: var(--gold-dark); }
html[data-theme="dark"] .soft .status-daily { color: var(--gold); }
/* Daily Offer publishing lane (web / app) */
.soft .status-lane      { background: var(--accent-soft); color: var(--accent); }

/* ── segmented tab bar ── */
.soft .tabbar {
  position: relative; display: flex; gap: 4px; padding: 4px;
  background: var(--glassbg); border: 1px solid var(--hair); border-radius: 14px;
  backdrop-filter: blur(28px) saturate(1.8);
  -webkit-backdrop-filter: blur(28px) saturate(1.8);
  box-shadow: var(--glass-inset), var(--glass-drop);
}
.soft .tabbar button, .soft .tabbar .tab-btn {
  flex: 1; font: inherit; font-size: 13px; font-weight: 600; color: var(--label2);
  background: none; border: 0; padding: 8px 16px; border-radius: 10px; cursor: pointer;
  transition: background .15s, color .15s, transform .16s ease; text-align: center;
}
.soft .tabbar button:hover, .soft .tabbar .tab-btn:hover { color: var(--label); background: var(--wash); transform: translateY(-1px); }
.soft .tabbar button.on, .soft .tabbar .tab-btn.on { color: var(--accent); background: var(--accent-soft); }

/* ── buttons (Trellis-wide names, soft skin) ── */
.soft .btn-primary {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font: inherit; font-size: 13px; font-weight: 600; color: #fff;
  background: var(--accent-fill); border: 0; border-radius: 100px; padding: 8px 16px;
  cursor: pointer;
  transition: transform .16s ease, box-shadow .22s ease, filter .15s;
}
.soft .btn-primary:hover { filter: brightness(1.08); transform: translateY(-1.5px); box-shadow: var(--btn-lift); }
.soft .btn-primary:active { transform: translateY(0); box-shadow: none; }
.soft .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; filter: none; }
.soft .btn-secondary {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--label2);
  background: var(--wash); border: 1px solid var(--hair); border-radius: 100px; padding: 7px 15px;
  cursor: pointer;
  transition: transform .16s ease, box-shadow .22s ease, background .15s, color .15s, border-color .15s;
}
.soft .btn-secondary:hover { color: var(--label); border-color: var(--hair2); transform: translateY(-1.5px); box-shadow: var(--btn-lift); }
.soft .btn-secondary:active { transform: translateY(0); box-shadow: none; }
.soft .btn-secondary:disabled { opacity: 0.4; cursor: not-allowed; transform: none; box-shadow: none; }
.soft .btn-danger {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--danger-fg);
  background: var(--danger-bg); border: 1px solid var(--danger-border); border-radius: 100px;
  padding: 7px 15px; cursor: pointer;
  transition: transform .16s ease, box-shadow .22s ease, filter .15s;
}
.soft .btn-danger:hover { filter: brightness(1.05); transform: translateY(-1.5px); box-shadow: var(--btn-lift); }
.soft .btn-danger:active { transform: translateY(0); box-shadow: none; }
.soft .btn-danger:disabled { opacity: 0.4; cursor: not-allowed; transform: none; box-shadow: none; }
/* carved chamfer rim at rest — same edge as cards, so buttons read as solid
   objects before hover (p_dash gives all faceted buttons this body) */
.soft .btn-primary::before, .soft .btn-secondary::before, .soft .btn-danger::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  padding: 1.2px; pointer-events: none; z-index: 2; opacity: 0.9;
  background: linear-gradient(148deg, var(--edge-hi), transparent 38%, transparent 62%, var(--edge-lo));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
/* quiet text button */
.soft .btn-quiet {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--label2);
  background: none; border: 0; padding: 6px 10px; border-radius: 9px; cursor: pointer;
  transition: background .15s, color .15s;
}
.soft .btn-quiet:hover { background: var(--wash); color: var(--label); }

/* ── inputs: engraved fields (Trellis-wide .field-input name) ── */
.soft .field-input,
.soft select.field-input {
  font: inherit; font-size: 13px; color: var(--label);
  background: var(--wash); border: 1px solid var(--hair); border-radius: 10px;
  padding: 8px 11px; outline: none; box-shadow: var(--carve-in);
  -webkit-appearance: none; appearance: none; min-width: 0;
  transition: border-color .16s ease, box-shadow .22s ease;
  color-scheme: inherit;
}
.soft .field-input::placeholder { color: var(--label3); }
.soft .field-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.soft .field-input:disabled { opacity: 0.45; cursor: not-allowed; }
/* appearance:none above strips the native arrow — draw our own chevron
   (mid-gray reads on both themes; data URIs can't reach the CSS vars) */
.soft select.field-input {
  padding-right: 30px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23898992' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 10px 6px;
}
/* keyboard-opened native menu fallback (soft-select.js only intercepts mouse) */
.soft select.field-input option { color: #1a1a21; background: #fff; }
.soft input[type="checkbox"], .soft input[type="radio"] { accent-color: var(--accent-fill); }
/* number fields: the native spinners clash with the soft idiom and eat the
   placeholder's room in narrow controls — hidden throughout the scope
   (typing and arrow keys still adjust the value) */
.soft input[type="number"]::-webkit-outer-spin-button,
.soft input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.soft input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

/* ── shared misc vocabulary ── */
/* Tailwind's .hidden utility (specificity 0,1,0) must keep beating the soft
   component rules that set display (.soft .banner-warn etc., 0,2,0) — page
   JS toggles visibility with it. */
.soft .hidden { display: none !important; }
.soft .empty-state { padding: 24px; text-align: center; color: var(--label3); font-size: 12.5px; }
.soft .banner-warn {
  display: flex; align-items: center; gap: 8px;
  background: var(--warn-bg); color: var(--warn-fg); border: 1px solid var(--warn-border);
  font-size: 12.5px; font-weight: 500; padding: 9px 13px; border-radius: 12px;
}
.soft .banner-info {
  display: flex; align-items: center; gap: 8px;
  background: var(--info-bg); color: var(--info-fg); border: 1px solid var(--hair);
  font-size: 12.5px; font-weight: 500; padding: 9px 13px; border-radius: 12px;
}

/* meters */
.soft .meter { height: 8px; border-radius: 5px; background: var(--track); overflow: hidden; position: relative; }
.soft .meter .fill { position: absolute; inset: 0 auto 0 0; border-radius: 5px; min-width: 2px; background: var(--accent-fill); transition: width .4s ease; }

/* tables */
.soft .tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.soft .tbl th {
  text-align: left; font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--label3);
  padding: 6px 9px; border-bottom: 1px solid var(--sep);
}
.soft .tbl td { padding: 7px 9px; color: var(--label2); border-bottom: 1px solid var(--wash); }
.soft .tbl th.num, .soft .tbl td.num { text-align: right; }

/* floating pop surface (menus, small popovers) */
.soft .glass-pop {
  background: var(--glasspop);
  backdrop-filter: blur(34px) saturate(1.8);
  -webkit-backdrop-filter: blur(34px) saturate(1.8);
  border: 1px solid var(--hair2); border-radius: 14px;
  box-shadow: var(--glass-inset), var(--soft-shadow);
}

/* custom select menu — soft-select.js suppresses the native (OS-drawn,
   unstylable, screen-escaping) dropdown and floats this listbox instead.
   Mounted on <body> like .soft-tip, so the glass surface is inlined here
   (.soft .glass-pop never matches an element outside a .soft subtree). */
.soft-select-pop {
  position: fixed; z-index: 400;
  max-height: min(320px, 44vh); max-width: min(360px, calc(100vw - 16px));
  overflow-y: auto; overscroll-behavior: contain; padding: 5px;
  background: var(--glasspop);
  backdrop-filter: blur(34px) saturate(1.8);
  -webkit-backdrop-filter: blur(34px) saturate(1.8);
  border: 1px solid var(--hair2); border-radius: 14px;
  box-shadow: var(--glass-inset), var(--soft-shadow);
  opacity: 0; transform: translateY(3px) scale(0.99);
  transition: opacity .14s ease, transform .14s ease;
}
.soft-select-pop.open { opacity: 1; transform: none; }
/* thin scrollbars for every scroll area in soft scopes: styled webkit bars
   run in classic mode and occupy their own gutter, unlike macOS overlay bars
   which paint OVER the content edge (padding alone can't keep those off card
   edges). Deliberately no scrollbar-width/scrollbar-color — setting either
   makes Chrome 121+ ignore the ::-webkit-scrollbar styling entirely. */
.soft::-webkit-scrollbar, .soft ::-webkit-scrollbar { width: 8px; height: 8px; }
.soft::-webkit-scrollbar-thumb, .soft ::-webkit-scrollbar-thumb { background: var(--hair2); border-radius: 4px; }
.soft::-webkit-scrollbar-track, .soft ::-webkit-scrollbar-track { background: transparent; }
.soft::-webkit-scrollbar-corner, .soft ::-webkit-scrollbar-corner { background: transparent; }
.soft-select-opt {
  position: relative; font-size: 13px; color: var(--label2);
  padding: 7px 11px 7px 28px; border-radius: 9px; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.soft-select-opt:hover, .soft-select-opt.hi { background: var(--wash); color: var(--label); }
.soft-select-opt.on { color: var(--label); font-weight: 600; }
.soft-select-opt.on::before { content: "✓"; position: absolute; left: 10px; color: var(--accent); font-weight: 700; }
.soft-select-opt.off { opacity: 0.4; cursor: default; }
.soft-select-opt.off:hover { background: none; color: var(--label2); }

/* floating hover hint — soft-tip.js upgrades [title] attributes into this */
.soft-tip {
  position: fixed; z-index: 300; max-width: 300px; pointer-events: none;
  background: var(--glasspop);
  backdrop-filter: blur(34px) saturate(1.8);
  -webkit-backdrop-filter: blur(34px) saturate(1.8);
  border: 1px solid var(--hair2); border-radius: 11px;
  box-shadow: var(--glass-inset), var(--soft-shadow);
  padding: 8px 12px; font-size: 12px; line-height: 1.5; color: var(--label2);
  opacity: 0; transform: translateY(2px);
  transition: opacity .15s ease, transform .15s ease;
}
.soft-tip.on { opacity: 1; transform: none; }

/* modal scaffolding */
.soft .scrim-bg { position: absolute; inset: 0; background: var(--scrimbg); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.soft .modal-shell {
  position: relative;
  background: var(--glasspop);
  backdrop-filter: blur(34px) saturate(1.8);
  -webkit-backdrop-filter: blur(34px) saturate(1.8);
  border: 1px solid var(--hair2); border-radius: 20px;
  box-shadow: var(--glass-inset), var(--soft-shadow);
  animation: soft-pop-in .18s cubic-bezier(.2, .9, .3, 1);
  transform-origin: top center;
}
@keyframes soft-pop-in {
  from { opacity: 0; transform: scale(.96) translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* hoverable list rows: flat card + lift (no backdrop blur — rows can be many) */
.soft .row-soft {
  position: relative; border-radius: 12px;
  transition: transform .16s ease, box-shadow .22s ease, background .15s;
}
.soft .row-soft:hover { transform: translateY(-1px); box-shadow: var(--row-lift); background: var(--wash); }

.soft ::selection { background: var(--accent-soft); }

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