/* ==========================================================================
   Webs Butler — portal design system
   One stylesheet for the logged-out tools landing and the logged-in portal.
   Light is the base; dark overrides only the tokens.
   ========================================================================== */

/* ---- tokens -------------------------------------------------------------- */
:root {
  --wb-brand-1: #8e2de2;
  --wb-brand-2: #4a00e0;
  --wb-brand-grad: linear-gradient(135deg, var(--wb-brand-1), var(--wb-brand-2));

  --wb-bg: #f4f1fd;
  --wb-bg-mesh-1: rgba(142, 45, 226, 0.16);
  --wb-bg-mesh-2: rgba(255, 94, 216, 0.13);
  --wb-bg-mesh-3: rgba(56, 189, 248, 0.10);

  --wb-surface: rgba(255, 255, 255, 0.74);
  --wb-surface-solid: #ffffff;
  --wb-surface-2: rgba(255, 255, 255, 0.46);
  --wb-surface-sunk: rgba(122, 90, 200, 0.06);

  --wb-text: #170a2b;
  --wb-text-soft: #4b4260;
  --wb-muted: #6f6788;

  --wb-border: rgba(94, 44, 180, 0.14);
  --wb-border-strong: rgba(94, 44, 180, 0.26);

  --wb-ok: #16a34a;
  --wb-ok-bg: rgba(22, 163, 74, 0.12);
  --wb-warn: #d97706;
  --wb-warn-bg: rgba(217, 119, 6, 0.13);
  --wb-bad: #dc2626;
  --wb-bad-bg: rgba(220, 38, 38, 0.12);

  --wb-shadow-sm: 0 2px 8px rgba(23, 10, 43, 0.06);
  --wb-shadow: 0 14px 40px -12px rgba(23, 10, 43, 0.20);
  --wb-shadow-lg: 0 30px 70px -24px rgba(23, 10, 43, 0.32);
  --wb-glow: 0 0 0 1px rgba(142, 45, 226, 0.28), 0 10px 34px -12px rgba(142, 45, 226, 0.62);

  --wb-r-sm: 10px;
  --wb-r: 16px;
  --wb-r-lg: 22px;
  --wb-r-pill: 999px;

  --wb-rail-w: 268px;
  --wb-bar-h: 68px;

  --wb-ease: cubic-bezier(0.22, 1, 0.36, 1);

  color-scheme: light;
}

:root[data-theme="dark"] {
  --wb-bg: #08060f;
  --wb-bg-mesh-1: rgba(142, 45, 226, 0.30);
  --wb-bg-mesh-2: rgba(236, 72, 153, 0.16);
  --wb-bg-mesh-3: rgba(56, 189, 248, 0.14);

  --wb-surface: rgba(23, 17, 41, 0.72);
  --wb-surface-solid: #150f28;
  --wb-surface-2: rgba(35, 26, 60, 0.44);
  --wb-surface-sunk: rgba(255, 255, 255, 0.04);

  --wb-text: #f0ecfb;
  --wb-text-soft: #c4bcdd;
  --wb-muted: #9990b5;

  --wb-border: rgba(167, 129, 255, 0.16);
  --wb-border-strong: rgba(167, 129, 255, 0.32);

  --wb-ok: #4ade80;
  --wb-ok-bg: rgba(74, 222, 128, 0.14);
  --wb-warn: #fbbf24;
  --wb-warn-bg: rgba(251, 191, 36, 0.14);
  --wb-bad: #f87171;
  --wb-bad-bg: rgba(248, 113, 113, 0.14);

  --wb-shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.45);
  --wb-shadow: 0 16px 44px -12px rgba(0, 0, 0, 0.72);
  --wb-shadow-lg: 0 34px 80px -26px rgba(0, 0, 0, 0.86);
  --wb-glow: 0 0 0 1px rgba(167, 129, 255, 0.36), 0 12px 40px -12px rgba(142, 45, 226, 0.72);

  color-scheme: dark;
}

/* ---- base ---------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.6;
  color: var(--wb-text);
  background: var(--wb-bg);
  -webkit-font-smoothing: antialiased;
  transition: background-color .4s var(--wb-ease), color .3s var(--wb-ease);
}

/* the mesh sits behind everything and never scrolls */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58ch 46ch at 12% -8%,  var(--wb-bg-mesh-1) 0, transparent 62%),
    radial-gradient(52ch 44ch at 92% 12%,  var(--wb-bg-mesh-2) 0, transparent 60%),
    radial-gradient(64ch 50ch at 68% 104%, var(--wb-bg-mesh-3) 0, transparent 62%);
  transition: opacity .4s var(--wb-ease);
}

a { color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  letter-spacing: -0.022em;
  line-height: 1.22;
  font-weight: 700;
}

::selection { background: rgba(142, 45, 226, 0.26); }

:focus-visible {
  outline: 2px solid var(--wb-brand-1);
  outline-offset: 2px;
  border-radius: 4px;
}

.wb-grad-text {
  background: var(--wb-brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ---- top bar ------------------------------------------------------------- */
.wb-bar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--wb-bar-h);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px;
  background: var(--wb-surface);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid var(--wb-border);
}

.wb-bar__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
}

.wb-bar__logo img {
  height: 26px;
  width: auto;
  display: block;
  transition: filter .3s var(--wb-ease);
}

/* the logo file is black artwork — invert it for dark mode rather than ship two files */
:root[data-theme="dark"] .wb-bar__logo img { filter: invert(1) brightness(1.9); }

.wb-bar__spacer { flex: 1; }

.wb-bar__group {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---- controls ------------------------------------------------------------ */
.wb-icon-btn {
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  background: var(--wb-surface-2);
  color: var(--wb-text-soft);
  cursor: pointer;
  padding: 0;
  transition: all .22s var(--wb-ease);
}

.wb-icon-btn:hover {
  color: var(--wb-brand-1);
  border-color: var(--wb-border-strong);
  transform: translateY(-1px);
}

.wb-icon-btn svg { width: 17px; height: 17px; }

/* segmented PL / EN */
.wb-seg {
  position: relative;
  display: flex;
  padding: 3px;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  background: var(--wb-surface-2);
}

.wb-seg__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: calc(50% - 3px);
  height: calc(100% - 6px);
  border-radius: var(--wb-r-pill);
  background: var(--wb-brand-grad);
  box-shadow: 0 4px 14px -4px var(--wb-brand-2);
  transition: transform .3s var(--wb-ease);
}

.wb-seg[data-i="1"] .wb-seg__thumb { transform: translateX(100%); }

.wb-seg button {
  position: relative;
  z-index: 1;
  min-width: 40px;
  padding: 5px 10px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--wb-muted);
  cursor: pointer;
  border-radius: var(--wb-r-pill);
  transition: color .25s var(--wb-ease);
}

.wb-seg button[aria-selected="true"] { color: #fff; }

/* buttons */
.wb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  border: 1px solid transparent;
  border-radius: var(--wb-r-pill);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: all .22s var(--wb-ease);
}

.wb-btn--primary {
  color: #fff;
  background: var(--wb-brand-grad);
  box-shadow: 0 10px 26px -10px var(--wb-brand-2);
}

.wb-btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 34px -10px var(--wb-brand-2);
}

.wb-btn--ghost {
  color: var(--wb-text-soft);
  background: var(--wb-surface-2);
  border-color: var(--wb-border);
}

.wb-btn--ghost:hover {
  color: var(--wb-brand-1);
  border-color: var(--wb-border-strong);
}

.wb-btn:disabled { opacity: .55; cursor: not-allowed; transform: none; }

.wb-btn--block { width: 100%; }

/* Sits inline with body text (the SEO summary row), so it has to be smaller
   than a standalone action button. */
.wb-btn--xs { padding: 5px 11px; font-size: .78rem; gap: 6px; }

/* ---- shell layout -------------------------------------------------------- */
.wb-shell {
  display: grid;
  grid-template-columns: var(--wb-rail-w) minmax(0, 1fr);
  align-items: start;
  gap: 22px;
  max-width: 1560px;
  margin: 0 auto;
  padding: 22px 20px 64px;
}

/* ---- left rail ----------------------------------------------------------- */
.wb-rail {
  position: sticky;
  top: calc(var(--wb-bar-h) + 22px);
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 16px 14px;
  background: var(--wb-surface);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-lg);
  box-shadow: var(--wb-shadow);
}

.wb-rail__title {
  padding: 0 10px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wb-muted);
}

.wb-rail__group { display: flex; flex-direction: column; gap: 4px; }
.wb-rail__group .wb-rail__title { margin-bottom: 6px; }

.wb-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-radius: var(--wb-r-sm);
  text-decoration: none;
  color: var(--wb-text-soft);
  font-size: 0.9rem;
  font-weight: 500;
  transition: all .2s var(--wb-ease);
}

.wb-nav__ico {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 9px;
  background: var(--wb-surface-sunk);
  color: var(--wb-muted);
  transition: all .2s var(--wb-ease);
}

.wb-nav__ico svg { width: 16px; height: 16px; }

.wb-nav:hover {
  background: var(--wb-surface-sunk);
  color: var(--wb-text);
}

.wb-nav:hover .wb-nav__ico { color: var(--wb-brand-1); }

.wb-nav--on {
  color: #fff;
  background: var(--wb-brand-grad);
  box-shadow: 0 10px 26px -12px var(--wb-brand-2);
}

.wb-nav--on .wb-nav__ico {
  background: rgba(255, 255, 255, 0.20);
  color: #fff;
}

/* .wb-nav:hover's plain surface background would otherwise win over the
   active gradient here (equal specificity, but .wb-nav:hover comes first) —
   this needs to come after it in source order to take over on hover. */
/* The active item gets no hover treatment: it is already the loudest thing in
   the rail, and tinting its icon to the brand purple sank it into the purple
   pill it sits on. Hover only needs to answer "is this clickable", which the
   filled state already does. */
.wb-nav--on:hover { background: var(--wb-brand-grad); color: #fff; }
.wb-nav--on:hover .wb-nav__ico { color: #fff; }

.wb-nav--locked { cursor: pointer; opacity: .62; }
.wb-nav--locked:hover { opacity: 1; }

.wb-nav__lock {
  margin-left: auto;
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  color: var(--wb-muted);
}

/* the upsell card at the bottom of the rail */
.wb-rail__cta {
  padding: 16px;
  border-radius: var(--wb-r);
  border: 1px solid var(--wb-border);
  background:
    linear-gradient(160deg, rgba(142, 45, 226, 0.12), rgba(74, 0, 224, 0.05));
  text-align: center;
}

.wb-rail__cta p {
  margin: 0 0 12px;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--wb-text-soft);
}

/* ---- main ---------------------------------------------------------------- */
.wb-main { min-width: 0; display: flex; flex-direction: column; gap: 20px; }

.wb-page-head { display: flex; flex-direction: column; gap: 6px; }
.wb-page-head h1 { font-size: clamp(1.5rem, 3vw, 2rem); }
.wb-page-head p { margin: 0; color: var(--wb-muted); font-size: 0.95rem; }

.wb-card {
  padding: 22px;
  background: var(--wb-surface);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-lg);
  box-shadow: var(--wb-shadow);
}

.wb-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 18px;
}

.wb-card__head h2 { font-size: 1.02rem; }

/* two-pane tool workspace: controls left, live result right */
.wb-work {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: 20px;
  align-items: start;
}

.wb-work__out { position: sticky; top: calc(var(--wb-bar-h) + 22px); }

/* ---- form fields --------------------------------------------------------- */
.wb-field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 15px; }
.wb-field:last-child { margin-bottom: 0; }

.wb-label {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--wb-muted);
}

.wb-input,
.wb-select,
.wb-textarea {
  width: 100%;
  padding: 12px 15px;
  font: inherit;
  font-size: 0.94rem;
  color: var(--wb-text);
  background: var(--wb-surface-solid);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-sm);
  outline: none;
  transition: border-color .2s var(--wb-ease), box-shadow .2s var(--wb-ease);
}

.wb-textarea { resize: vertical; min-height: 96px; }

.wb-input:focus,
.wb-select:focus,
.wb-textarea:focus {
  border-color: var(--wb-brand-1);
  box-shadow: 0 0 0 3px rgba(142, 45, 226, 0.16);
}

.wb-input::placeholder, .wb-textarea::placeholder { color: var(--wb-muted); opacity: .75; }

.wb-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* colour swatch input */
.wb-color {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px 7px 7px;
  background: var(--wb-surface-solid);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-sm);
}

.wb-color input[type="color"] {
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  cursor: pointer;
}

.wb-color input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.wb-color input[type="color"]::-webkit-color-swatch { border: 1px solid var(--wb-border); border-radius: 8px; }
.wb-color span { font-size: 0.84rem; font-weight: 600; color: var(--wb-text-soft); font-variant-numeric: tabular-nums; }

/* pill tabs */
.wb-tabs {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 2px;
  padding: 4px;
  margin-bottom: 18px;
  background: var(--wb-surface-sunk);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
}

.wb-tabs__thumb {
  position: absolute;
  top: 4px;
  left: 4px;
  height: calc(100% - 8px);
  border-radius: var(--wb-r-pill);
  background: var(--wb-brand-grad);
  box-shadow: 0 6px 18px -6px var(--wb-brand-2);
  transition: transform .32s var(--wb-ease);
}

.wb-tabs button {
  position: relative;
  z-index: 1;
  padding: 9px 14px;
  border: 0;
  background: none;
  border-radius: var(--wb-r-pill);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--wb-muted);
  cursor: pointer;
  transition: color .25s var(--wb-ease);
}

.wb-tabs button[aria-selected="true"] { color: #fff; }

/* choice chips (dot style, quality level, …) */
.wb-chips { display: flex; flex-wrap: wrap; gap: 8px; }

.wb-chip {
  position: relative;
  padding: 9px 16px;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  background: var(--wb-surface-solid);
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--wb-text-soft);
  cursor: pointer;
  transition: all .2s var(--wb-ease);
}

.wb-chip input { position: absolute; opacity: 0; pointer-events: none; }

.wb-chip:has(input:checked) {
  color: #fff;
  background: var(--wb-brand-grad);
  border-color: transparent;
  box-shadow: 0 8px 20px -8px var(--wb-brand-2);
}

/* dropzone */
.wb-drop {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 18px;
  text-align: left;
  border: 1.5px dashed var(--wb-border-strong);
  border-radius: var(--wb-r-sm);
  background: var(--wb-surface-sunk);
  color: var(--wb-muted);
  font-size: 0.87rem;
  cursor: pointer;
  transition: all .2s var(--wb-ease);
}

/* without this the icon has no intrinsic size and stretches to fill the box */
.wb-drop svg { width: 18px; height: 18px; flex-shrink: 0; }

/* the tall variant, for tools where the drop target is the primary action */
.wb-drop--tall {
  flex-direction: column;
  padding: 30px 20px;
  text-align: center;
  border-radius: var(--wb-r);
}

.wb-drop--tall svg { width: 26px; height: 26px; }

.wb-drop:hover, .wb-drop.is-over {
  border-color: var(--wb-brand-1);
  color: var(--wb-brand-1);
  background: rgba(142, 45, 226, 0.07);
}

.wb-drop input[type="file"] { display: none; }

/* ---- file rows (compressor) ---------------------------------------------- */
.wb-files { display: flex; flex-direction: column; gap: 8px; }

.wb-file {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  overflow: hidden;
  background: var(--wb-surface-solid);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-sm);
}

.wb-file__thumb {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: 8px;
  background: var(--wb-surface-sunk);
  cursor: pointer;
}

.wb-file__body { flex: 1; min-width: 0; }

.wb-file__name {
  display: block;
  font-size: 0.88rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.wb-file__name:hover { color: var(--wb-brand-1); }

.wb-file__meta {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 2px;
  font-size: 0.79rem;
  color: var(--wb-muted);
  font-variant-numeric: tabular-nums;
}

.wb-file__meta strong { color: var(--wb-text); font-weight: 700; }

.wb-file__acts { display: flex; gap: 6px; flex-shrink: 0; }

.wb-file__btn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--wb-border);
  border-radius: 9px;
  background: none;
  color: var(--wb-muted);
  cursor: pointer;
  transition: all .2s var(--wb-ease);
}

.wb-file__btn svg { width: 15px; height: 15px; }

/* per-file download carries a word, not just an arrow — one file at a time is
   the common case, and an unlabelled icon reads as decoration */
.wb-file__dl { padding: 7px 14px; font-size: 0.82rem; }
.wb-file__dl svg { width: 14px; height: 14px; }
@media (max-width: 620px) { .wb-file__dl span { display: none; } .wb-file__dl { padding: 7px 10px; } }
.wb-file__btn:hover:not(:disabled) { color: var(--wb-brand-1); border-color: var(--wb-border-strong); }
.wb-file__btn:disabled { opacity: .35; cursor: not-allowed; }
.wb-file__btn.is-del:hover { color: var(--wb-bad); border-color: var(--wb-bad); }

.wb-file__bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 0;
  background: var(--wb-brand-grad);
  transition: width .3s var(--wb-ease);
}

.wb-file__bar.is-bad { background: var(--wb-bad); }

/* saving badge, green when the file actually got smaller */
.wb-save-pill {
  padding: 2px 9px;
  border-radius: var(--wb-r-pill);
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--wb-ok);
  background: var(--wb-ok-bg);
}

/* ---- badges & meta ------------------------------------------------------- */
.wb-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 11px;
  border-radius: var(--wb-r-pill);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.wb-badge--ok   { color: var(--wb-ok);   background: var(--wb-ok-bg); }
.wb-badge--warn { color: var(--wb-warn); background: var(--wb-warn-bg); }
.wb-badge--bad  { color: var(--wb-bad);  background: var(--wb-bad-bg); }
.wb-badge--mut  { color: var(--wb-muted); background: var(--wb-surface-sunk); }

/* who is signed in — top bar identity chip */
.wb-who {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 260px;
  padding: 5px 14px 5px 5px;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  background: var(--wb-surface-2);
  text-decoration: none;
  transition: all .2s var(--wb-ease);
}

.wb-who:hover { border-color: var(--wb-border-strong); background: var(--wb-surface-sunk); }

.wb-who__av {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 50%;
  color: #fff;
  font-size: 0.82rem;
  font-weight: 800;
  background: var(--wb-brand-grad);
}

.wb-who__txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }

.wb-who__txt strong {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--wb-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wb-who__txt em {
  font-size: 0.68rem;
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--wb-muted);
}

@media (max-width: 780px) { .wb-who__txt { display: none; } .wb-who { padding: 5px; } }

/* the free-use counter in the top bar */
.wb-credits {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px 6px 8px;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  background: var(--wb-surface-2);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--wb-text-soft);
}

.wb-credits__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--wb-ok);
  box-shadow: 0 0 0 3px var(--wb-ok-bg);
}

.wb-credits--out .wb-credits__dot { background: var(--wb-bad); box-shadow: 0 0 0 3px var(--wb-bad-bg); }

/* ---- tool grid (landing) ------------------------------------------------- */
.wb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 16px;
}

.wb-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  background: var(--wb-surface);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-lg);
  box-shadow: var(--wb-shadow-sm);
  transition: transform .3s var(--wb-ease), box-shadow .3s var(--wb-ease), border-color .3s var(--wb-ease);
}

/* a soft light that follows nothing — just lifts the card on hover */
.wb-tile::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(142, 45, 226, 0.6), transparent 46%, rgba(74, 0, 224, 0.45));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0;
  transition: opacity .3s var(--wb-ease);
  pointer-events: none;
}

.wb-tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--wb-shadow-lg);
}

.wb-tile:hover::after { opacity: 1; }

.wb-tile__ico {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  color: #fff;
  background: var(--wb-brand-grad);
  box-shadow: 0 10px 24px -10px var(--wb-brand-2);
}

.wb-tile__ico svg { width: 22px; height: 22px; }

.wb-tile h3 { font-size: 1.02rem; }

.wb-tile p {
  margin: 0;
  font-size: 0.87rem;
  line-height: 1.55;
  color: var(--wb-muted);
}

.wb-tile__foot {
  margin-top: auto;
  padding-top: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--wb-brand-1);
}

/* ---- empty state --------------------------------------------------------- */
.wb-empty {
  display: grid;
  place-items: center;
  gap: 10px;
  padding: 56px 24px;
  text-align: center;
  color: var(--wb-muted);
}

.wb-empty__ico {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 16px;
  background: var(--wb-surface-sunk);
  color: var(--wb-brand-1);
}

/* ---- modal / login wall -------------------------------------------------- */
.wb-modal {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(12, 6, 26, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: wb-fade .22s var(--wb-ease);
}

.wb-modal[hidden] { display: none; }

.wb-modal__box {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: 30px 28px 26px;
  text-align: center;
  background: var(--wb-surface-solid);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-lg);
  box-shadow: var(--wb-shadow-lg);
  animation: wb-pop .28s var(--wb-ease);
}

.wb-modal__ico {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  margin: 0 auto 16px;
  border-radius: 16px;
  color: #fff;
  background: var(--wb-brand-grad);
  box-shadow: 0 12px 28px -10px var(--wb-brand-2);
}

.wb-modal__ico svg { width: 24px; height: 24px; }

.wb-modal__box h2 { font-size: 1.18rem; margin-bottom: 8px; }

.wb-modal__box p {
  margin: 0 0 20px;
  font-size: 0.91rem;
  line-height: 1.6;
  color: var(--wb-muted);
}

.wb-modal__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--wb-r-pill);
  background: none;
  color: var(--wb-muted);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
}

.wb-modal__close:hover { color: var(--wb-text); background: var(--wb-surface-sunk); }

@keyframes wb-fade { from { opacity: 0; } }
@keyframes wb-pop  { from { opacity: 0; transform: translateY(12px) scale(.97); } }

/* ---- toast --------------------------------------------------------------- */
.wb-toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  z-index: 95;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--wb-text);
  background: var(--wb-surface-solid);
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-pill);
  box-shadow: var(--wb-shadow-lg);
  animation: wb-rise .3s var(--wb-ease);
}

@keyframes wb-rise { from { opacity: 0; transform: translate(-50%, 14px); } }

/* ---- lang visibility ----------------------------------------------------- */
[data-lang-pl], [data-lang-en] { display: none; }
:root[data-lang="pl"] [data-lang-pl] { display: revert; }
:root[data-lang="en"] [data-lang-en] { display: revert; }

/* ---- utilities ----------------------------------------------------------- */
.wb-stack { display: flex; flex-direction: column; gap: 14px; }
.wb-hstack { display: flex; align-items: center; gap: 10px; }
.wb-muted { color: var(--wb-muted); }
.wb-small { font-size: 0.83rem; }
.wb-hide { display: none !important; }
.wb-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- navigation chrome: burger, drawer, collapse ------------------------- */

/* Hidden on desktop; the drawer it opens only exists below the breakpoint. */
.wb-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0 9px;
  flex-shrink: 0;
  border: 1px solid var(--wb-border);
  border-radius: var(--wb-r-sm);
  background: var(--wb-surface-2);
  cursor: pointer;
}

.wb-burger span {
  display: block;
  height: 2px;
  width: 100%;
  border-radius: 2px;
  background: var(--wb-text);
  transition: transform .28s var(--wb-ease), opacity .18s var(--wb-ease);
}

body.wb-nav-open .wb-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.wb-nav-open .wb-burger span:nth-child(2) { opacity: 0; }
body.wb-nav-open .wb-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.wb-rail-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgba(10, 4, 22, .45);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity .28s var(--wb-ease);
}
body.wb-nav-open .wb-rail-scrim { opacity: 1; }

/* Phone-only block of header controls that live inside the drawer instead. */
.wb-rail__utils { display: none; flex-direction: column; gap: 4px; }
.wb-rail__utils-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px 2px;
}

/* Desktop-only collapse control. */
.wb-rail__collapse {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding: 9px 12px;
  border: 1px solid transparent;
  border-radius: var(--wb-r-sm);
  background: none;
  color: var(--wb-muted);
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: all .2s var(--wb-ease);
}
.wb-rail__collapse:hover { background: var(--wb-surface-sunk); color: var(--wb-text); }
.wb-rail__collapse svg { flex-shrink: 0; transition: transform .28s var(--wb-ease); }

/* NB: .wb-collapse-ico is a <span>, so a blanket
   `.wb-rail__collapse span { display:none }` here would hide the icon itself
   and leave the hover target blank. Only the text label is hidden — and the
   button has no text label any more, so nothing is listed. */
:root[data-rail="collapsed"] .wb-rail__cta,
:root[data-rail="collapsed"] .wb-nav__lock { display: none; }
:root[data-rail="collapsed"] .wb-nav { justify-content: center; padding: 9px 0; }

/* The label itself becomes the tooltip when collapsed — no duplicated string
   to translate, so it follows the PL/EN switch for free. */
:root[data-rail="collapsed"] .wb-nav > span:not(.wb-nav__ico) {
  position: absolute;
  /* Clears the rail's own padding and border so the bubble floats free of the
     panel edge rather than butting up against it. */
  left: calc(100% + 20px);
  top: 50%;
  z-index: 45;
  transform: translateY(-50%) translateX(-4px);
  padding: 7px 11px;
  border-radius: 9px;
  background: var(--wb-text);
  color: var(--wb-surface);
  font-size: .82rem;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  box-shadow: var(--wb-shadow);
  transition: opacity .18s var(--wb-ease), transform .18s var(--wb-ease);
}
:root[data-rail="collapsed"] .wb-nav:hover > span:not(.wb-nav__ico),
:root[data-rail="collapsed"] .wb-nav:focus-visible > span:not(.wb-nav__ico) {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* ---- responsive ---------------------------------------------------------- */
@media (max-width: 1180px) {
  .wb-work { grid-template-columns: minmax(0, 1fr); }
  .wb-work__out { position: static; }
}

@media (max-width: 900px) {
  .wb-shell { grid-template-columns: minmax(0, 1fr); padding: 16px 14px 48px; }
  .wb-bar__logo img { height: 22px; }

  .wb-burger { display: flex; }
  .wb-bar__group--wide { display: none; }
  .wb-rail__collapse { display: none; }
  .wb-rail__utils { display: flex; }

  /* The rail leaves the grid entirely and becomes an overlay drawer, entering
     from the right so it sits under the thumb next to the burger. */
  .wb-rail {
    position: fixed;
    top: 0;
    left: auto;
    right: 0;
    z-index: 60;
    width: min(84vw, 310px);
    height: 100%;
    margin: 0;
    border-radius: var(--wb-r-lg) 0 0 var(--wb-r-lg);
    border-right: 0;
    border-top: 0;
    border-bottom: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    transition: transform .3s var(--wb-ease);
  }
  body.wb-nav-open .wb-rail { transform: translateX(0); }
  body.wb-nav-open { overflow: hidden; }

  /* Collapsing is a desktop affordance; it must not follow the rail into the
     drawer, or the drawer would open as an icon strip. */
  :root[data-rail="collapsed"] .wb-shell { grid-template-columns: minmax(0, 1fr); }
  :root[data-rail="collapsed"] .wb-rail { padding: 16px 14px; }
  :root[data-rail="collapsed"] .wb-rail__title { display: block; }
  :root[data-rail="collapsed"] .wb-nav { justify-content: flex-start; padding: 11px 12px; }
  :root[data-rail="collapsed"] .wb-nav > span:not(.wb-nav__ico) {
    position: static;
    transform: none;
    padding: 0;
    border-radius: 0;
    background: none;
    color: inherit;
    font-size: .9rem;
    font-weight: 500;
    opacity: 1;
    box-shadow: none;
  }
}

@media (max-width: 560px) {
  .wb-row { grid-template-columns: 1fr; }
  .wb-bar { padding: 0 14px; gap: 10px; }
  .wb-card { padding: 17px; }
}

@media (min-width: 901px) {
  .wb-rail-scrim { display: none; }
}

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


/* ==========================================================================
   Rail: fixed, detached, collapsible
   --------------------------------------------------------------------------
   The rail leaves the page grid on desktop and floats as a fixed panel, so
   the main column gets the full remaining width instead of sharing it with a
   grid track that is no longer occupied.
   ========================================================================== */

:root {
  --wb-rail-gap: 20px;        /* how far the panel floats off every edge */
  --wb-rail-w-collapsed: 76px;
}

/* ---- top row: wordmark, and the collapse control ------------------------- */
.wb-rail__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 14px;
}

.wb-rail__logo { display: flex; align-items: center; min-width: 0; }
.wb-rail__logo-img { max-width: 148px; width: 100%; height: auto; }
.wb-rail__logo-img-collapsed { display: none; width: 34px; height: auto; }

/* The wordmark ships as black artwork, so dark mode inverts it rather than
   shipping a second file. The glow is a drop-shadow on the alpha channel,
   which traces the letterforms instead of boxing them. */
:root[data-theme="dark"] .wb-rail__logo-img,
:root[data-theme="dark"] .wb-rail__logo-img-collapsed {
  filter: invert(1) brightness(1.9)
          drop-shadow(0 0 6px rgba(168, 120, 255, .45))
          drop-shadow(0 0 14px rgba(120, 70, 220, .3));
}

.wb-collapse-ico { display: flex; align-items: center; justify-content: center; }
.wb-collapse-ico svg { width: 18px; height: 18px; }

/* ---- vertical rhythm ----------------------------------------------------
   Tuned so the whole rail fits without scrolling on a laptop screen: a
   scrollbar here would sit over the panel's rounded right edge and square it
   off. The scrollbar chrome is hidden as a backstop for very short windows —
   the rail still scrolls by wheel, it just never shows a bar. */
.wb-rail { scrollbar-width: none; -ms-overflow-style: none; }
.wb-rail::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* Desktop only: phones keep the roomier rows, since the drawer scrolls
   anyway and fingers need the target. Measured to fit a 1440x768 laptop
   with headroom to about 690px tall. */
@media (min-width: 901px) {
  /* Breathing room between rows comes from the group gap rather than row
     padding: padding would enlarge each row's hit area and, times twelve
     rows, is what pushes the rail past a 768px-tall screen. The tighter
     outer paddings below pay for the extra gap. */
  .wb-rail { gap: 6px; padding: 8px 14px; }
  .wb-rail__top { padding-bottom: 6px; }
  .wb-rail__group { gap: 8px; }
  .wb-rail__group .wb-rail__title { margin-bottom: 0; }
  .wb-rail .wb-nav { padding: 5px 12px; }
  .wb-rail .wb-nav__ico { width: 28px; height: 28px; }
}

/* ---- desktop: float the panel, free the main column --------------------- */
@media (min-width: 901px) {
  .wb-rail {
    position: fixed;
    top: var(--wb-rail-gap);
    left: var(--wb-rail-gap);
    z-index: 50;
    width: var(--wb-rail-w);
    height: calc(100vh - var(--wb-rail-gap) * 2);
    border: 1px solid var(--wb-border);
    border-radius: var(--wb-r-lg);
    overflow-y: auto;
  }

  /* Single column: the rail is out of flow, so a rail-sized grid track would
     just be dead space squeezing the tools. Width comes from padding instead. */
  .wb-shell {
    grid-template-columns: minmax(0, 1fr);
    max-width: none;
    padding: 22px var(--wb-rail-gap) 64px
             calc(var(--wb-rail-w) + var(--wb-rail-gap) * 2);
  }
  .wb-main { width: 100%; max-width: 1240px; margin: 0 auto; }

  :root[data-rail="collapsed"] .wb-rail { width: var(--wb-rail-w-collapsed); }
  :root[data-rail="collapsed"] .wb-shell {
    padding-left: calc(var(--wb-rail-w-collapsed) + var(--wb-rail-gap) * 2);
  }

  /* Collapsed labels are tooltips that sit outside the panel, so this one
     cannot clip. Icons alone always fit, so nothing needs to scroll here. */
  :root[data-rail="collapsed"] .wb-rail { overflow: visible; }

  .wb-bar__logo { display: none; }
}

/* ---- collapsed: icon strip ----------------------------------------------
   Desktop-scoped on purpose. The collapsed choice is remembered per browser,
   so data-rail="collapsed" is still set when the same session is opened on a
   phone — unscoped, these cosmetics would shrink the drawer's icons and blank
   out its section headings. */
.wb-rail__logo { transition: opacity .2s var(--wb-ease); }

@media (min-width: 901px) {
  :root[data-rail="collapsed"] .wb-rail { padding: 14px 10px; }
  :root[data-rail="collapsed"] .wb-rail__logo-img { display: none; }
  :root[data-rail="collapsed"] .wb-rail__logo-img-collapsed { display: block; filter: brightness(0); }
  :root[data-theme="dark"][data-rail="collapsed"] .wb-rail__logo-img-collapsed {
    filter: brightness(0) invert(1)
            drop-shadow(0 0 6px rgba(168, 120, 255, .45))
            drop-shadow(0 0 14px rgba(120, 70, 220, .3));
  }

  /* Bigger, box-free icons: dropping the tinted tile is what buys the
     contrast, since the glyph then sits on the panel rather than a pale chip. */
  /* The glyph grows (16 -> 21) while its hit box shrinks a little: without
     the tinted tile the box is invisible anyway, and the taller collapsed
     rows are what would otherwise push the strip past the viewport. */
  :root[data-rail="collapsed"] .wb-rail .wb-nav { padding: 4px 0; }
  :root[data-rail="collapsed"] .wb-rail .wb-nav__ico {
    width: 34px;
    height: 34px;
    background: none;
    color: var(--wb-text-soft);
  }
  :root[data-rail="collapsed"] .wb-rail .wb-nav__ico svg { width: 21px; height: 21px; }
  :root[data-rail="collapsed"] .wb-nav:not(.wb-nav--on):hover .wb-nav__ico { color: var(--wb-brand-1); }
  :root[data-rail="collapsed"] .wb-nav--on .wb-nav__ico,
  :root[data-rail="collapsed"] .wb-nav--on:hover .wb-nav__ico { background: none; color: #fff; }
  :root[data-rail="collapsed"] .wb-nav--logout .wb-nav__ico { color: inherit; }

  /* The wordmark swaps to an expand affordance on hover. */
  :root[data-rail="collapsed"] .wb-rail__top {
    position: relative;
    justify-content: center;
    min-height: 40px;
  }
  :root[data-rail="collapsed"] .wb-rail__collapse {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    justify-content: center;
    background: none;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s var(--wb-ease);
  }
  :root[data-rail="collapsed"] .wb-rail__top:hover .wb-rail__collapse { opacity: 1; pointer-events: auto; }
  :root[data-rail="collapsed"] .wb-rail__top:hover .wb-rail__logo { opacity: 0; }
  :root[data-rail="collapsed"] .wb-rail__collapse .wb-collapse-ico svg { transform: rotate(180deg); }
}

/* Section headings become hairlines rather than disappearing, so the grouping
   survives the collapse. Desktop-scoped for the same reason as above. */
@media (min-width: 901px) {
  :root[data-rail="collapsed"] .wb-rail__title {
    height: 1px;
    margin: 6px 8px 7px;
    padding: 0;
    font-size: 0;
    background: var(--wb-border);
  }
}

/* On a short window the icon strip can still run past the panel, and with
   overflow visible it would spill down the page instead of stopping at the
   rounded edge. Below this height it scrolls instead — the tooltips clip,
   which is the lesser of the two problems, and the bar stays hidden. */
@media (min-width: 901px) and (max-height: 720px) {
  :root[data-rail="collapsed"] .wb-rail { overflow-y: auto; }
}

/* ---- top bar: chrome only ----------------------------------------------- */
.wb-bar {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom: none;
  pointer-events: none;
}
.wb-bar > * { pointer-events: auto; }

/* ---- sign out, pinned to the foot of the rail --------------------------- */
.wb-nav--logout { margin-top: auto; color: var(--wb-bad); }
.wb-nav--logout:hover { background: var(--wb-bad-bg, rgba(220, 53, 69, .08)); color: var(--wb-bad); }
.wb-nav--logout .wb-nav__ico { color: inherit; }

/* ---- phones: burger and drawer both on the right ------------------------ */
@media (max-width: 900px) {
  .wb-bar__logo { display: flex; }
  .wb-burger { order: 9; margin-left: auto; }
  .wb-rail__top { display: none; }
}
