  * { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; }
  svg { display: block; }

  /* overflow:hidden clips the decorative ::after glow, which sticks 20px past the
     right edge and would otherwise give the whole page a horizontal scrollbar on mobile. */
  header.masthead { position: relative; overflow: hidden; background: var(--card); border-bottom: 1px solid var(--line); }
  header.masthead::before {
    content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
    background: linear-gradient(90deg, var(--brand), var(--accent));
  }
  header.masthead::after {
    content: ""; position: absolute; top: -40px; right: -20px; width: 360px; height: 210px; pointer-events: none;
    background: radial-gradient(60% 80% at 72% 18%, color-mix(in srgb, var(--brand) 13%, transparent), transparent 70%);
  }
  .masthead-inner {
    position: relative; z-index: 2; max-width: 1040px; margin: 0 auto;
    padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; gap: 14px;
  }
  /* Sizing/layout of the lockup lives in base.css; this is the link behaviour only.
     BEZ reakcji na hover: logotyp jest znakiem marki, a przygaszanie go pod kursorem
     czytało się jak wyłączony przycisk. Klikalny zostaje (wraca na listę) — sygnalizuje to
     sam kursor; jedyny element lockupu z podświetleniem to „TrafficWatchdog" (base.css),
     bo tamten prowadzi na inny serwis. */
  .brand { text-decoration: none; cursor: pointer; }
  .masthead-title { position: relative; z-index: 2; max-width: 1040px; margin: 0 auto; padding: 6px 20px 22px; }
  .masthead-title h1 { margin: 8px 0 14px; font-size: clamp(24px, 4.4vw, 33px); font-weight: 800; letter-spacing: -.025em; color: var(--ink); }
  .masthead-title h1 .em { background: linear-gradient(90deg, var(--brand), var(--accent)); -webkit-background-clip: text; background-clip: text; color: transparent; }
  .masthead-title h1 .em .em-plain { color: var(--ink); -webkit-text-fill-color: var(--ink); }
  .client-card {
    display: flex; flex-wrap: wrap; gap: 14px 30px; align-items: stretch;
    margin-top: 18px; padding: 14px 18px;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
  }
  .cc-item { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .cc-label { font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--muted-2); }
  .cc-value { font-size: 15px; font-weight: 700; color: var(--ink); display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .cc-swatch { width: 15px; height: 15px; border-radius: 5px; flex: 0 0 15px; box-shadow: inset 0 0 0 1px rgba(16,24,40,.12); }
  .cc-platforms { display: inline-flex; flex-wrap: wrap; gap: 6px; justify-content: flex-start; }
  .cc-plat {
    display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
    font-size: 11px; font-weight: 800; letter-spacing: .01em; padding: 3px 9px 3px 7px; border-radius: 999px;
  }
  .cc-plat-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 6px; }
  .cc-plat.is-on { color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.2); }
  .cc-plat.is-on .cc-plat-dot { background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.16); }
  .cc-plat.is-off { background: color-mix(in srgb, var(--ink) 6%, var(--card)); color: var(--muted-2); }
  .cc-plat.is-off .cc-plat-dot { background: var(--muted-2); }


  .wrap { max-width: 1040px; margin: 0 auto; padding: 0 20px 72px; }


  .progress-wrap { display: flex; align-items: center; gap: 12px; margin: 16px 2px 4px; }
  .progress {
    flex: 1; height: 8px; border-radius: 999px; background: var(--brand-ghost);
    overflow: hidden; box-shadow: inset 0 0 0 1px var(--line);
  }
  .progress-fill {
    height: 100%; width: 0; border-radius: 999px;
    background: linear-gradient(90deg, var(--brand), var(--accent));
    transition: width .45s cubic-bezier(.2,.7,.3,1);
  }
  .progress-label { font-size: 12.5px; font-weight: 700; color: var(--muted); white-space: nowrap; }


  .tab-panel { display: none; }
  .tab-panel.is-active { display: block; animation: fade .25s ease; }
  @keyframes fade { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }

  .section-title {
    font-size: 12px; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); margin: 22px 4px 14px; font-weight: 800;
  }

  .card-foot {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 14px 16px; border-top: 1px solid var(--line-soft); background: var(--card-soft);
  }
  .post-status { font-size: 13px; color: var(--muted); flex: 1; min-width: 160px; line-height: 1.45; }
  .social-card .card-foot { flex-direction: column; align-items: stretch; gap: 10px; }
  .social-card .post-status.is-empty { display: none; }
  .foot-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
  .foot-actions .btn { padding: 9px 15px; }
  .post-status a { color: var(--brand); font-weight: 600; word-break: break-all; }
  .post-status .ok { color: var(--ok); font-weight: 700; }
  .post-status .err { color: var(--err); font-weight: 700; }
  .post-status.ok { color: var(--ok); }
  .post-status.err { color: var(--err); }
  .spinner {
    display: inline-block; width: 13px; height: 13px; border: 2px solid var(--brand-line);
    border-top-color: var(--brand); border-radius: 50%; animation: spin .7s linear infinite;
    vertical-align: -2px; margin-right: 6px;
  }
  @keyframes spin { to { transform: rotate(360deg); } }

  .post-article {
    position: relative;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); overflow: hidden; margin-bottom: 22px;
  }
  .article-inner { padding: 40px clamp(24px, 5vw, 56px) 8px; }
  .article-kicker { display: inline-flex; }
  .article-title {
    margin: 16px 0 14px; font-family: var(--serif); font-weight: 700;
    font-size: clamp(28px, 4.4vw, 42px); line-height: 1.12; letter-spacing: -.012em; color: var(--ink);
    text-wrap: balance;
  }
  .article-dek {
    margin: 0; font-family: var(--serif); font-size: clamp(17px, 2.4vw, 20px);
    line-height: 1.5; color: var(--muted); font-weight: 400; text-wrap: pretty;
  }
  .article-meta {
    display: flex; align-items: center; gap: 12px; margin-top: 24px;
    padding-top: 22px; border-top: 1px solid var(--line-soft);
  }
  .meta-avatar {
    width: 42px; height: 42px; border-radius: 50%; flex: 0 0 42px;
    background: linear-gradient(135deg, var(--brand), var(--brand-deep));
    color: #fff; display: flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: 17px; text-transform: uppercase;
  }
  .meta-text { line-height: 1.3; }
  .meta-name { font-weight: 700; font-size: 14.5px; color: var(--ink); }
  .meta-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; display: flex; align-items: center; gap: 6px; }
  .meta-sub .draft-pill {
    font-size: 10.5px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
    color: var(--warn-ink); background: var(--warn-bg); border: 1px solid var(--warn-line); padding: 2px 8px; border-radius: 999px;
  }
  .article-hero { margin: 28px clamp(24px, 5vw, 56px) 4px; }
  .article-hero img {
    display: block; width: 100%; height: auto; border-radius: 14px;
    box-shadow: var(--shadow-sm); border: 1px solid var(--line-soft);
  }
  .article-hero figcaption { margin-top: 9px; font-size: 12.5px; color: var(--muted-2); text-align: center; }
  .article-body { padding: 12px clamp(24px, 5vw, 56px) 28px; }
  .article-frame {
    width: 100%; border: 0; display: block; background: #fff; height: 600px;
    transition: height .2s ease;
  }
  :root[data-theme="dark"] .article-frame,
  :root[data-theme="dark"] .article-edit-frame { background: var(--card); }
  .article-frame.is-collapsed { height: 540px; -webkit-mask-image: linear-gradient(#000 78%, transparent); mask-image: linear-gradient(#000 78%, transparent); }
  .article-expand { display: none; justify-content: center; padding: 0 0 24px; margin-top: -8px; }
  .article-expand.show { display: flex; }

  /* Compound selector (0,2,0) so the absolute pin beats the later `.edit-split { position: relative }`
     rule the dropdown feature added — otherwise the article edit menu falls into normal flow. */
  .edit-split.article-edit-corner { position: absolute; top: 16px; right: 16px; z-index: 6; }

  .article-editor { padding: 4px clamp(24px, 5vw, 56px) 20px; }
  .article-editor[hidden] { display: none; }
  .article-edit-frame {
    width: 100%; display: block; min-height: 320px;
    border: 1px solid var(--brand); border-radius: 12px; background: #fff;
    box-shadow: 0 0 0 3px var(--brand-ghost);
  }
  .article-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-bottom: 10px; }
  .article-toolbar button {
    appearance: none; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 700;
    color: var(--ink-2); background: var(--card); border: 1px solid var(--line); border-radius: 8px;
    padding: 6px 11px; min-width: 34px; line-height: 1.2;
    transition: background .15s, border-color .15s, color .15s;
  }
  .article-toolbar button:hover { background: var(--brand-ghost); border-color: var(--brand-line); color: var(--brand-strong); }
  .article-toolbar .tb-bold { font-weight: 900; }
  .article-toolbar .tb-italic { font-style: italic; font-family: Georgia, serif; }
  .article-toolbar .tb-sep { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }
  .article-seo-fields { display: grid; gap: 14px; margin: 16px 0 14px; }
  .article-seo-fields[hidden] { display: none; }
  .article-seo-label {
    display: block; margin-bottom: 6px; font-size: 11.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase; color: var(--muted);
  }
  .article-seo-input, .article-seo-textarea {
    width: 100%; box-sizing: border-box; background: var(--card);
    border: 1px solid var(--brand); border-radius: var(--radius-sm); padding: 10px 14px;
    box-shadow: 0 0 0 3px var(--brand-ghost);
  }
  .article-seo-input {
    font-family: var(--serif); font-weight: 700; font-size: clamp(22px, 3.4vw, 32px);
    line-height: 1.2; letter-spacing: -.01em; color: var(--ink);
  }
  .article-seo-textarea {
    font-family: var(--serif); font-size: clamp(16px, 2.2vw, 19px); line-height: 1.5;
    color: var(--muted); resize: vertical; min-height: 64px;
  }
  .article-seo-input:focus, .article-seo-textarea:focus { outline: none; border-color: var(--brand-strong); }
  .article-editor-hint { display: block; font-size: 12.5px; line-height: 1.45; color: var(--muted); margin: 10px 0 0; }
  .article-editor-btns { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
  .post-article .card-foot {
    position: sticky; bottom: 0; z-index: 5;
    background: color-mix(in srgb, var(--card-soft) 92%, transparent); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  }
  /* Empty article status (pending) collapses so the action row can hug the card's right edge;
     the actions grow to fill and stay right-aligned (both publish buttons on the right). */
  .post-article .post-status:empty { display: none; }
  .post-article .foot-actions { flex: 1 1 auto; }

  .social-stage {
    max-width: 1040px; margin: 8px auto 0;
    columns: 2; column-gap: 22px;
  }
  .social-card {
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); overflow: hidden; min-width: 0;
    break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid;
    margin: 0 0 22px;
  }
  @media (max-width: 620px) { .social-stage { columns: 1; } }
  .sc-head { display: flex; align-items: center; gap: 11px; padding: 13px 14px; }
  .sc-avatar {
    width: 42px; height: 42px; border-radius: 50%; flex: 0 0 42px; position: relative;
    color: #fff; display: flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: 17px; text-transform: uppercase;
    background: var(--brand);
  }
  .sc-avatar.ig { background: radial-gradient(circle at 30% 110%, #fdf497 0%, #fd5949 42%, #d6249f 60%, #285AEB 92%); }
  .sc-avatar.tt { background: #010101; }
  .sc-avatar.tt::after {
    content: ""; position: absolute; right: -2px; bottom: -2px; width: 16px; height: 16px; border-radius: 50%;
    background: linear-gradient(135deg, #25f4ee 30%, #fe2c55 70%); border: 2px solid var(--card);
  }
  .sc-avatar.fb { background: #1877f2; }
  .sc-avatar.yt { background: #ff0000; color: transparent; }
  .sc-avatar.yt::after {
    content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-44%, -50%);
    width: 0; height: 0;
    border-left: 13px solid #fff; border-top: 8px solid transparent; border-bottom: 8px solid transparent;
  }
  .sc-avatar.ig-ring { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px #fd5949; }
  .sc-who { min-width: 0; line-height: 1.3; flex: 1; }
  .sc-name { font-weight: 700; font-size: 14px; color: var(--ink); display: inline-flex; align-items: center; gap: 4px; }
  .sc-name .verified { color: var(--brand); }
  .sc-sub { font-size: 12px; color: var(--muted); margin-top: 1px; display: flex; align-items: center; gap: 5px; }
  .sc-sub .globe { width: 12px; height: 12px; color: var(--muted-2); }
  .sc-more { margin-left: auto; background: none; border: 0; cursor: default; color: var(--muted); padding: 4px; flex: 0 0 auto; }
  .sc-badge {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
    padding: 5px 11px 5px 9px; border-radius: 999px; white-space: nowrap;
    color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.22);
  }
  .sc-badge .pill-dot {
    width: 6px; height: 6px; border-radius: 50%; flex: 0 0 6px;
    background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.18);
  }
  .badge--article   { background: var(--brand-grad); }
  .badge--blog      { background: var(--brand-grad); }
  .badge--facebook  { background: radial-gradient(circle at 28% 112%, #5ea2f6 0%, #1877f2 72%); }
  .badge--instagram { background: radial-gradient(circle at 28% 112%, #fdf497 0%, #fd5949 42%, #d6249f 62%, #285aeb 92%); }
  .badge--tiktok    { background: radial-gradient(circle at 24% 112%, #25f4ee 0%, #111 46%, #fe2c55 100%); }
  .badge--youtube   { background: radial-gradient(circle at 28% 112%, #ff6a6a 0%, #ff0000 72%); }

  .sc-caption {
    padding: 2px 15px 13px; white-space: pre-wrap; word-wrap: break-word;
    font-size: 14px; line-height: 1.5; color: var(--ink-2);
  }
  .sc-caption .cap-name { font-weight: 700; color: var(--ink); margin-right: 6px; }
  .sc-caption.is-empty .cap-text::before {
    content: var(--i18n-caption-empty); color: var(--muted-2); font-style: italic;
  }
  .sc-caption.fb-text { font-size: 15px; color: var(--ink); padding-bottom: 11px; }

  .caption-tools { padding: 0 15px 12px; }
  .edit-corner {
    appearance: none; border: 1px solid var(--line); background: var(--card); cursor: pointer; font-family: inherit;
    color: var(--brand); font-weight: 700; font-size: 12.5px; padding: 5px 10px; border-radius: 999px;
    display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; white-space: nowrap;
    transition: background .15s, color .15s, border-color .15s;
  }
  .edit-corner:hover { background: var(--brand-ghost); color: var(--brand-strong); border-color: var(--brand-line); }
  .edit-corner svg { width: 14px; height: 14px; }

  /* Edit/Delete dropdown (posts + article) */
  .edit-split { position: relative; display: inline-flex; }
  .edit-split .edit-corner { gap: 5px; }
  .edit-corner .edit-caret { width: 12px; height: 12px; margin-left: 1px; opacity: .8; }
  .edit-more-trigger { margin-left: 0; cursor: pointer; border-radius: 999px; transition: background .15s, color .15s; }
  .edit-more-trigger:hover { background: var(--brand-ghost); color: var(--brand-strong); }
  .edit-menu {
    position: fixed; z-index: 60; min-width: 180px; padding: 6px; display: none;
    background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow);
  }
  .edit-split.menu-open .edit-menu { display: block; }
  .edit-menu-item {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; cursor: pointer;
    background: none; border: 0; border-radius: 8px; padding: 9px 11px;
    font-family: inherit; font-size: 13px; font-weight: 600; color: var(--ink-2);
    transition: background .15s, color .15s;
  }
  .edit-menu-item svg { width: 15px; height: 15px; flex: 0 0 15px; }
  .edit-menu-item:hover { background: var(--brand-ghost); color: var(--brand-strong); }
  .edit-menu-item.danger { color: var(--err); }
  .edit-menu-item.danger:hover { background: var(--err-bg); color: var(--err); }

  /* Delete confirmation modal */
  /* z-index jak .modal-overlay — potwierdzenie usunięcia też potrafi wyjść z otwartego
     kafelka i musi przykryć jego krzyżyk (121). */
  .rv-modal { position: fixed; inset: 0; z-index: 130; display: none; }
  .rv-modal.is-open { display: block; }
  .rv-modal-overlay { position: absolute; inset: 0; background: rgba(10,16,28,.55); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
  .rv-modal-dialog {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: min(440px, calc(100vw - 32px)); box-sizing: border-box;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 24px 24px 20px;
  }
  .rv-modal-title { font-size: 18px; font-weight: 800; color: var(--ink); margin: 0 0 8px; letter-spacing: -.01em; }
  .rv-modal-body { font-size: 14px; line-height: 1.55; color: var(--ink-2); margin: 0 0 20px; }
  .rv-modal-btns { display: flex; justify-content: flex-end; gap: 10px; }
  .btn.danger { background: var(--err); box-shadow: 0 1px 2px rgba(16,24,40,.08), 0 6px 16px color-mix(in srgb, var(--err) 26%, transparent); }
  .btn.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--err) 88%, #000); box-shadow: 0 10px 26px color-mix(in srgb, var(--err) 40%, transparent); }
  .caption-input {
    width: 100%; box-sizing: border-box; resize: none; overflow: hidden; min-height: 120px;
    font-family: inherit; font-size: 14px; line-height: 1.5; color: var(--ink-2);
    border: 1px solid var(--brand-line); border-radius: var(--radius-sm); padding: 11px 13px; background: var(--card);
  }
  .caption-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ghost); }
  .caption-editor-btns { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
  .caption-editor-btns .btn { padding: 8px 16px; }
  .emoji-btn {
    appearance: none; cursor: pointer; font-family: inherit; font-size: 17px; line-height: 1;
    border: 1px solid var(--line); background: var(--card); border-radius: 999px;
    width: 34px; height: 34px; flex: 0 0 auto; margin-right: auto;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background .15s, border-color .15s;
  }
  .emoji-btn:hover { background: var(--brand-ghost); border-color: var(--brand-line); }
  .emoji-pop {
    position: fixed; z-index: 60; width: 300px; max-height: 300px; overflow: auto;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: var(--shadow); padding: 10px;
  }
  .emoji-pop[hidden] { display: none; }
  .emoji-cat { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted-2); margin: 10px 4px 6px; }
  .emoji-cat:first-child { margin-top: 2px; }
  .emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
  .emoji-grid button {
    appearance: none; border: 0; background: none; cursor: pointer; font-size: 20px; line-height: 1;
    padding: 5px 0; border-radius: 8px; transition: background .12s;
  }
  .emoji-grid button:hover { background: var(--brand-ghost); }

  .sc-media { position: relative; background: #0c0d10; }
  .sc-media img, .sc-media video { display: block; width: 100%; }
  .sc-media.single img, .sc-media.single video { max-height: 600px; object-fit: contain; margin: 0 auto; }
  /* Zanim doleci metadata, <video> nie ma naturalnych proporcji i karta stoi w domyślnym
     prostokącie. `auto <ratio>` = użyj naturalnych, gdy będą znane, a do tego czasu 9:16
     (TikTok/YouTube generujemy pionowo) — dzięki temu kafelek nie skacze przy wczytaniu. */
  .social-card--tiktok .sc-media.single video,
  .social-card--youtube .sc-media.single video { aspect-ratio: auto 9 / 16; }

  .carousel { position: relative; }
  .carousel-track {
    display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .carousel-track::-webkit-scrollbar { display: none; }
  .carousel-track > .slide { scroll-snap-align: center; flex: 0 0 100%; }
  .carousel-track > .slide img, .carousel-track > .slide video {
    width: 100%; aspect-ratio: 4 / 5; object-fit: contain; background: #0c0d10;
  }
  .carousel.story .carousel-track > .slide { flex: 0 0 100%; }
  .carousel.story .carousel-track > .slide img, .carousel.story .carousel-track > .slide video {
    aspect-ratio: 9 / 16; object-fit: cover;
  }
  .fb-carousel { background: var(--card); }
  .fb-ccard { background: var(--card); }
  .fb-carousel .carousel-track > .slide img, .fb-carousel .carousel-track > .slide video {
    aspect-ratio: 1 / 1; object-fit: cover; background: #0c0d10;
  }
  .fb-ccard-foot {
    background: var(--line-soft); padding: 10px 12px; border-top: 1px solid var(--line);
    display: flex; flex-direction: column; gap: 2px;
  }
  .fb-ccard-domain { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
  .fb-ccard-name {
    font-weight: 700; font-size: 14px; line-height: 1.3; color: var(--ink);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .fb-ccard-desc {
    font-size: 13px; color: var(--muted); line-height: 1.35;
    display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
  }
  .car-counter {
    position: absolute; top: 12px; right: 12px; z-index: 3;
    font-size: 12px; font-weight: 700; color: #fff;
    background: rgba(16,18,22,.62); backdrop-filter: blur(4px);
    padding: 4px 11px; border-radius: 999px; letter-spacing: .02em;
    opacity: 1; transition: opacity .2s;
  }
  .car-arrow {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
    width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer;
    background: rgba(255,255,255,.92); color: #1a1c22; box-shadow: 0 2px 8px rgba(0,0,0,.22);
    display: flex; align-items: center; justify-content: center;
    transition: opacity .18s ease, transform .12s ease;
  }
  .car-arrow:hover { transform: translateY(-50%) scale(1.06); }
  .car-arrow.prev { left: 10px; }
  .car-arrow.next { right: 10px; }
  .car-arrow[disabled] { opacity: 0; pointer-events: none; }
  .car-dots {
    display: flex; justify-content: center; gap: 6px; padding: 11px 0 3px;
  }
  .car-dots .cdot {
    width: 6px; height: 6px; border-radius: 50%; background: color-mix(in srgb, var(--brand) 26%, var(--line));
    transition: transform .2s, background .2s;
  }
  .car-dots .cdot.active { background: var(--brand); transform: scale(1.5); }

  .sc-actions-ig {
    display: flex; align-items: center; gap: 16px; padding: 10px 14px 4px; color: var(--ink);
  }
  .sc-actions-ig svg { width: 25px; height: 25px; cursor: default; }
  .sc-actions-ig .spacer { flex: 1; }
  .sc-actions-fb {
    display: flex; align-items: stretch; padding: 4px 6px; margin: 0 8px; border-top: 1px solid var(--line-soft);
  }
  .sc-actions-fb button {
    flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    background: none; border: 0; cursor: default; padding: 9px 4px;
    font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--muted); border-radius: 8px;
  }
  .sc-actions-fb button svg { width: 19px; height: 19px; }
  .sc-meta-fb {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 9px 15px 2px; font-size: 12.5px; color: var(--muted);
  }
  .sc-meta-fb .reacts { display: inline-flex; align-items: center; gap: 6px; }
  .sc-meta-fb .react-ico {
    width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
    color: #fff; background: #1877f2; box-shadow: 0 0 0 2px var(--card);
  }
  .sc-meta-fb .react-ico svg { width: 11px; height: 11px; }

  .sc-actions-tt { display: flex; align-items: center; gap: 16px; padding: 11px 14px 4px; color: var(--ink); }
  .sc-actions-tt .tt-act { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--ink-2); }
  .sc-actions-tt svg { width: 23px; height: 23px; }
  .sc-actions-tt .spacer { flex: 1; }

  .sc-yt-title { padding: 11px 15px 0; font-size: 15px; font-weight: 700; line-height: 1.3; color: var(--ink); }
  .sc-actions-yt { display: flex; align-items: center; gap: 8px; padding: 9px 14px 4px; flex-wrap: wrap; }
  .yt-likepill { display: inline-flex; align-items: center; background: color-mix(in srgb, var(--ink) 5%, var(--card)); border-radius: 999px; }
  .yt-likepill .yt-like { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; font-size: 13px; font-weight: 700; color: var(--ink-2); }
  .yt-likepill .yt-like + .yt-like { border-left: 1px solid var(--line); }
  .yt-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 5%, var(--card)); font-size: 13px; font-weight: 700; color: var(--ink-2); }
  .sc-actions-yt svg, .yt-likepill svg { width: 18px; height: 18px; }


  .empty {
    text-align: center; color: var(--muted); padding: 60px 20px; margin-top: 26px; max-width: 520px;
    margin-left: auto; margin-right: auto;
    background: var(--card); border: 1px dashed var(--line); border-radius: var(--radius);
  }
  .empty .ico { display: flex; justify-content: center; margin-bottom: 12px; color: var(--muted-2); }

  .toast {
    position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(8px);
    background: var(--ink); color: var(--bg); padding: 12px 20px; border-radius: 12px;
    font-size: 14px; font-weight: 600; opacity: 0; pointer-events: none;
    transition: opacity .25s ease, transform .25s ease; z-index: 140;
    box-shadow: 0 12px 34px rgba(0,0,0,.3);
  }
  .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

  .masthead-actions { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; }
  .report-btn { flex: 0 0 auto; }
  .report-btn svg { width: 16px; height: 16px; }
  .report-card-btn { margin-right: auto; padding: 9px 13px !important; }
  .report-card-btn svg { flex: 0 0 auto; }
  /* Merged top bar (onboarding progress + test-version banner) follows the scroll as ONE sticky
     element; the sticky topnav is pushed below it by its measured height (--topbar-h, set by the
     onboarding IIFE's syncTopbars). */
  .topbar { position: sticky; top: 0; z-index: 40; }
  .onb-banner {
    display: flex; align-items: center; gap: 10px;
    padding: 12px clamp(16px, 4vw, 40px);
    background: var(--brand-ghost); border-bottom: 1px solid var(--brand-line);
    color: var(--ink-2); font-size: 13.5px; font-weight: 600;
  }
  .onb-banner.is-error {
    background: var(--err-bg);
    border-bottom-color: color-mix(in srgb, var(--err) 30%, var(--card));
    color: var(--err);
  }
  .onb-banner.is-success {
    background: var(--ok-bg);
    border-bottom-color: color-mix(in srgb, var(--ok) 30%, var(--card));
    color: var(--ok);
  }
  /* Test-version (idle, no active progress state): a warm amber tone distinct from the
     brand/success/error states so "you're on the testing version" reads as a standing notice. */
  .onb-banner.is-test {
    background: var(--warn-bg); border-bottom-color: color-mix(in srgb, var(--warn) 34%, var(--card));
    color: var(--warn-ink);
  }
  /* Public demo (/preview): the brand gradient, because this row is the only piece of
     MARKETING on either page — it says "this is a showcase" and sells the free demo, and it
     must not be mistaken for one of the client-facing notices above it. Mirrored by
     .test-banner.is-demo in settings.css — keep the two in sync. */
  .onb-banner.is-demo, .test-banner.is-demo {
    background: linear-gradient(90deg, var(--brand), var(--accent));
    border-bottom-color: transparent; color: #fff;
  }
  .onb-banner.is-demo .onb-sub, .test-banner.is-demo .onb-sub { opacity: .86; }
  /* Inverted CTA: on the gradient a --brand button disappears into the background. */
  .onb-banner.is-demo .demo-cta, .test-banner.is-demo .demo-cta {
    background: #fff; color: var(--brand); font-weight: 800;
  }
  .onb-banner.is-demo .demo-cta:hover, .test-banner.is-demo .demo-cta:hover { background: #fff; opacity: .9; }
  .onb-flask { flex: none; font-size: 15px; line-height: 1; }
  /* Test-row CTA — identical to the settings page banner button (keep the two in sync). */
  .test-cta { flex: none; margin-left: auto; padding: 7px 16px; font-size: 13px; white-space: nowrap; background: var(--brand); color: #fff; border-color: transparent; }
  /* "Twój plan: <nazwa>" + its CTA, right-aligned in the tab row (where the Sklep tab used to be). */
  .nav-plan { display: flex; align-items: center; gap: 9px; margin-left: auto; padding-left: 18px; }
  .nav-plan-label { font-size: 12.5px; font-weight: 700; color: var(--muted-2); white-space: nowrap; }
  .nav-plan-value { font-size: 13.5px; font-weight: 800; color: var(--muted); white-space: nowrap; }
  .nav-plan-value.is-set { color: var(--brand-strong); }
  /* Bezpłatny test — jeden z pięciu stanów chipa, więc pigułka jest SAMĄ wartością, a nie
     plakietką doklejoną obok niej. Ten sam ok-owy język co .post-status i plakietka „Bezpłatny
     test" na karcie progu. */
  .nav-plan-value.is-trial {
    font-size: 11.5px; letter-spacing: .01em;
    padding: 2px 9px; border-radius: 999px; cursor: default;
    color: var(--ok); background: var(--ok-bg);
    border: 1px solid color-mix(in srgb, var(--ok) 34%, var(--card));
  }
  .nav-plan-cta { padding: 7px 14px; font-size: 12.5px; white-space: nowrap; }
  /* Prominent animated "activate plan" CTA — the no-plan-yet variant. */
  .ib-plan-cta {
    flex: none; display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 16px; border-radius: 999px; font-size: 13px; font-weight: 800; white-space: nowrap;
    color: #fff; text-decoration: none; position: relative; overflow: hidden;
    background: linear-gradient(100deg, var(--brand), var(--accent));
    box-shadow: 0 4px 14px -4px color-mix(in srgb, var(--brand) 60%, transparent);
    transition: transform .18s cubic-bezier(.22,.8,.3,1), box-shadow .18s;
  }
  .ib-plan-cta:hover { transform: translateY(-1px) scale(1.02); box-shadow: 0 8px 20px -5px color-mix(in srgb, var(--brand) 70%, transparent); }
  .ib-plan-cta:active { transform: translateY(0) scale(.99); }
  /* Shine sweep across the pill. */
  .ib-plan-cta::after {
    content: ""; position: absolute; top: 0; left: -60%; width: 45%; height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.5), transparent);
    transform: skewX(-18deg); animation: ib-shine 3.4s ease-in-out infinite;
  }
  @keyframes ib-shine { 0%,18% { left: -60%; } 42%,100% { left: 130%; } }
  .ib-plan-spark { font-size: 12px; animation: ib-spark 1.8s ease-in-out infinite; }
  @keyframes ib-spark { 0%,100% { transform: scale(1); opacity: .85; } 50% { transform: scale(1.35) rotate(20deg); opacity: 1; } }
  @media (prefers-reduced-motion: reduce) { .ib-plan-cta::after, .ib-plan-spark { animation: none; } }
  .infobars .client-card { align-items: center; }
  .onb-check { flex: none; font-weight: 800; font-size: 15px; line-height: 1; }
  .onb-msg { flex: 1 1 auto; }
  /* Done state: a two-line hand-off (headline + "you're on the testing version" sub). */
  .onb-banner-text { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; }
  .onb-banner-text .onb-msg { flex: none; }
  .onb-sub { font-size: 12.5px; font-weight: 600; opacity: .82; }
  .onb-banner-cta { flex: none; margin-left: auto; padding: 7px 16px; font-size: 13px; white-space: nowrap; }
  .onb-spin {
    width: 15px; height: 15px; flex: none; border-radius: 50%;
    border: 2px solid var(--brand-line); border-top-color: var(--brand);
    animation: onb-spin .8s linear infinite;
  }
  @keyframes onb-spin { to { transform: rotate(360deg); } }
  /* The onboarding OVERLAY's own styles (card, steps, e-mail row, consent box) live in
     static/css/onboarding/{shell,steps}.css — they are shared with the settings page and are
     nothing to do with this page's banners. Only the `.onb-banner`/`.onb-spin` topbar rows
     above belong here. */

  .day-list { display: block; }
  .day-section { margin-bottom: 4px; }
  .day-list .section-title { display: none; }


  .masthead-sub { margin: 0; font-size: 15px; font-weight: 600; color: var(--muted); }

  /* /preview masthead: copy left, marketplace call-out + chips in the right half of the same
     band (bottom-aligned to the pitch line) — stacking them under the copy pushed everything
     below the masthead down for nothing. Phones stack + left-align it in the 560px block. */
  .masthead-title.split { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px 30px; flex-wrap: wrap; }
  .masthead-title.split .mt-copy { min-width: 0; }
  .plat-promo { text-align: right; flex: 0 0 auto; }
  .plat-promo .plat-cta { font-size: 13.5px; }
  /* 2×2 grid rather than a wrapping row: four chips in one line are wider than the pitch
     line to their left, and any width change (a longer locale label) reflowed the copy.
     The block is a fixed two-column shape instead, pinned to the right edge; chips stretch
     to their column and center their content so the edges stay flush. */
  .plat-promo .plat-links {
    display: grid; grid-template-columns: repeat(2, minmax(0, auto));
    justify-content: end; margin-top: 8px;
  }
  .plat-promo .plat-link { justify-content: center; }

  /* Marketplace chips under the masthead subtitle — /preview only (see review.html).
     The plate stays white in BOTH themes on purpose: these are third-party wordmarks with
     baked-in near-black glyphs (IdoSell), so they can't inherit the page's ink. */
  .plat-links { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
  .plat-link {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px; border-radius: 999px; text-decoration: none;
    background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-sm);
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
  }
  .plat-link:hover {
    transform: translateY(-1px); box-shadow: var(--shadow);
    border-color: color-mix(in srgb, var(--brand) 45%, var(--line));
  }
  .plat-link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
  .plat-link-mark { height: 14px; width: auto; }
  /* The WordPress mark is square; the WooCommerce badge is a wide 24×5.24 strip (its SVG is
     cropped to the ink), so both are sized by width and left to keep their own ratio. */
  .plat-link-ico { width: 14px; height: auto; }
  .plat-link-ico.wide { width: 19px; }
  .plat-link-txt { font-size: 12.5px; font-weight: 800; letter-spacing: -.01em; color: #171717; white-space: nowrap; }
  @media (prefers-reduced-motion: reduce) { .plat-link:hover { transform: none; } }

  .cc-accounts { display: inline-flex; flex-wrap: wrap; gap: 5px 14px; }
  .cc-acct { display: inline-flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 700; color: var(--ink); }
  .cc-acct-ico { width: 15px; height: 15px; display: flex; flex: 0 0 15px; }
  .cc-acct-ico.fb { color: #1877f2; }
  .cc-acct-ico.ig { color: #d6249f; }
  .cc-acct-ico.tt { color: var(--ink); }
  .cc-acct-ico.yt { color: #ff0000; }
  .cc-none { font-size: 14px; font-weight: 600; color: var(--muted-2); font-style: italic; }

  .topnav {
    position: sticky; top: var(--topbar-h, 0px); z-index: 20;
    background: var(--card); border-bottom: 1px solid var(--line); box-shadow: var(--shadow-sm);
  }
  .navbar { max-width: 1040px; margin: 0 auto; padding: 0 20px; display: flex; align-items: stretch; }
  .nav-btn {
    appearance: none; border: 0; cursor: pointer; font-family: inherit;
    display: inline-flex; align-items: center; gap: 9px;
    padding: 15px 20px; font-size: 15px; font-weight: 700;
    color: var(--muted); background: transparent; border-bottom: 3px solid transparent;
    transition: color .15s, background .15s, border-color .15s;
  }
  .nav-btn .nav-ico { width: 18px; height: 18px; display: flex; flex: 0 0 18px; color: var(--acc); }
  .nav-btn:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 4%, transparent); }
  .nav-btn[data-tab="blog"]   { --acc: #1f86c9; --acc-soft: #289be5; }
  .nav-btn[data-tab="social"] { --acc: #c026a6; --acc-soft: #d6249f; }
  .nav-btn[data-tab="video"]  { --acc: #e11d48; --acc-soft: #ff5858; }
  .nav-btn.is-active { color: var(--acc); border-bottom-color: var(--acc-soft); background: color-mix(in srgb, var(--acc-soft) 10%, transparent); }
  .nav-count {
    font-size: 11.5px; font-weight: 800; min-width: 19px; height: 19px; padding: 0 6px;
    display: inline-flex; align-items: center; justify-content: center; border-radius: 999px;
    background: color-mix(in srgb, var(--acc-soft) 15%, var(--card)); color: var(--acc);
  }
  .nav-btn.is-active .nav-count { background: color-mix(in srgb, var(--acc-soft) 22%, var(--card)); }
  .nav-soon {
    font-size: 9.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
    color: var(--muted-2); background: color-mix(in srgb, var(--ink) 7%, var(--card)); padding: 2px 6px; border-radius: 6px;
  }
  .infobars { border-top: 1px solid var(--line-soft); }
  .infobars[hidden] { display: none; }
  .infobars .client-card {
    display: none;
    max-width: 1040px; margin: 0 auto; padding: 12px 20px;
    border: 0; border-radius: 0; box-shadow: none; background: transparent;
  }
  .infobars .client-card.is-active { display: flex; }

  .subbar {
    margin: 18px 0 16px; padding: 10px 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-sm);
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px;
  }
  .subbar[hidden] { display: none; }
  .subbar-left { justify-self: start; display: flex; align-items: center; min-width: 0; }
  .subbar-center { justify-self: center; }
  .subbar-right { justify-self: end; }
  .view-count { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--muted); white-space: nowrap; }
  .view-count .vc-ico { width: 15px; height: 15px; color: var(--muted-2); flex: 0 0 15px; }

  .seg { display: inline-flex; background: color-mix(in srgb, var(--ink) 5%, var(--card)); border: 1px solid var(--line); border-radius: 11px; padding: 3px; gap: 2px; }
  .seg-btn {
    appearance: none; border: 0; cursor: pointer; font-family: inherit;
    display: inline-flex; align-items: center; gap: 8px;
    padding: 7px 14px; border-radius: 8px; font-size: 13px; font-weight: 700;
    color: var(--muted); background: transparent; transition: color .15s, background .15s, box-shadow .15s;
  }
  .seg-btn:hover { color: var(--ink-2); }
  .seg-btn.is-active { color: var(--ink); background: var(--card); box-shadow: var(--shadow-sm); }
  .seg-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
  .seg-btn[data-status="pending"] .seg-dot { background: var(--warn); }
  .seg-btn[data-status="published"] .seg-dot { background: var(--ok); }
  .seg-count { font-size: 11px; font-weight: 800; color: var(--muted-2); min-width: 12px; }
  .seg-btn.is-active .seg-count { color: var(--muted); }

  /* Przełącznik widoku listy blogowej — ten sam komponent co filtr statusu po prawej. */
  .view-seg { margin-right: 10px; }
  .view-seg[hidden] { display: none; }
  .view-seg .seg-btn { padding: 7px 11px; gap: 6px; }
  .view-seg .seg-ico { width: 15px; height: 15px; flex: 0 0 15px; display: block; }
  .view-seg .seg-ico svg { width: 100%; height: 100%; display: block; }

  .daynav { display: inline-flex; align-items: stretch; background: var(--card); border: 1px solid var(--brand-line); border-radius: 14px; overflow: hidden; box-shadow: var(--shadow-sm); }
  .daynav-arrow {
    appearance: none; border: 0; cursor: pointer; background: transparent; color: var(--brand-strong);
    padding: 0 16px; display: inline-flex; align-items: center; transition: background .15s, color .15s;
  }
  .daynav-arrow:hover:not(:disabled) { background: var(--brand-ghost); }
  .daynav-arrow:disabled { color: var(--muted-2); opacity: .4; cursor: default; }
  .daynav-arrow svg { width: 21px; height: 21px; }
  .daynav-label {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 9px 26px; min-width: 200px; text-align: center;
    border-left: 1px solid var(--brand-line); border-right: 1px solid var(--brand-line);
  }
  .daynav-date { font-size: 16px; font-weight: 800; color: var(--ink); white-space: nowrap; letter-spacing: -.01em; }
  .daynav-idx { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
  .daynav[hidden] { display: none; }

  /* Reused by connect_notice() (the "link an account" card). */
  .report-placeholder {
    padding: 56px 40px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 16px;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
  }
  .report-placeholder .rp-ico { width: 64px; height: 64px; border-radius: 18px; display: flex; align-items: center; justify-content: center; background: var(--brand-ghost); color: var(--brand-strong); }
  .report-placeholder h2 { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
  .report-placeholder p { margin: 0; max-width: 440px; color: var(--muted); font-size: 15px; line-height: 1.55; }

  /* --- Shop tab (subscription tiers + contact form) --- */
  .shop-wrap { max-width: 1040px; margin: 8px auto 0; }
  .shop-head { text-align: center; margin-bottom: 26px; }
  .shop-head h2 { margin: 0 0 8px; font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
  .shop-head p { margin: 0 auto; max-width: 520px; color: var(--muted); font-size: 15px; line-height: 1.55; }
  /* Currency picker: a quiet inline row under the subtitle, never a section of its own —
     the panel's job is to sell a package, and most clients never touch this. The control
     itself is the shared .lang-select pill (base.css). */
  .shop-cur { display: inline-flex; align-items: center; gap: 9px; margin-top: 16px; }
  .shop-cur-label { font-size: 13px; font-weight: 600; color: var(--muted); }
  .shop-cur-select { font-size: 12.5px; padding-block: 7px; }
  .tier-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: stretch; padding-top: 12px; }
  /* Drops to one column early (900, not 760): the cards now carry the add-on rows, and a
     narrower card wraps the row's price onto its own line. */
  @media (max-width: 900px) { .tier-grid { grid-template-columns: 1fr; } }
  .tier-card {
    position: relative; display: flex; flex-direction: column; gap: 12px;
    background: var(--card); border: 1px solid var(--line); border-radius: 18px;
    box-shadow: var(--shadow); padding: 38px 20px 22px; overflow: hidden; isolation: isolate;
    transition: transform .22s cubic-bezier(.22,.8,.3,1), box-shadow .22s, border-color .22s;
    /* `backwards`, NOT `both`: a filled-forwards animation keeps its final `transform: none`
       applied for good, which silently killed the featured card's scale and every hover lift
       (an animation's own value beats a normal declaration). */
    animation: tier-in .5s cubic-bezier(.22,.8,.3,1) backwards; animation-delay: calc(var(--i, 0) * 90ms);
  }
  @keyframes tier-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
  /* Gradient accent strip along the top edge + a soft radial glow bloom behind the icon. */
  .tier-card::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; z-index: 1;
    background: linear-gradient(90deg, var(--tier-a), var(--tier-b));
  }
  .tier-card::after {
    content: ""; position: absolute; top: -40px; left: 50%; width: 200px; height: 140px; z-index: -1;
    transform: translateX(-50%); border-radius: 50%; opacity: .14; filter: blur(26px);
    background: radial-gradient(circle, var(--tier-b), transparent 70%);
  }
  .tier-card:hover { transform: translateY(-6px); box-shadow: 0 22px 40px -22px color-mix(in srgb, var(--tier-a) 65%, transparent), var(--shadow); border-color: color-mix(in srgb, var(--tier-a) 40%, var(--line)); }
  .tier-card.is-featured { border-color: color-mix(in srgb, var(--tier-a) 55%, var(--line)); box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--tier-a) 45%, transparent), var(--shadow); }
  @media (min-width: 901px) { .tier-card.is-featured { transform: scale(1.04); } .tier-card.is-featured:hover { transform: translateY(-6px) scale(1.04); } }
  /* Centred on the top edge (the card clips its own corners, so the pill keeps a flat top
     and rounds only downwards) — every tier card reserves the same padding-top for it. */
  .tier-badge {
    position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    background: linear-gradient(90deg, var(--tier-a), var(--tier-b)); color: #fff;
    font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
    padding: 6px 14px 5px; border-radius: 0 0 999px 999px; white-space: nowrap;
    box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--tier-a) 70%, transparent);
  }
  .tier-badge:not(.tier-badge--current)::before { content: "★ "; }
  /* The tier the client is already on: ribbon + ring inherit THAT tier's own gradient (the old
     flat green read as a status sticker bolted onto the card rather than part of it). */
  .tier-badge--current { box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--tier-a) 70%, transparent), inset 0 0 0 1px rgba(255,255,255,.35); }
  .tier-card.is-current { border-color: color-mix(in srgb, var(--tier-a) 55%, var(--line)); box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--tier-a) 45%, transparent), var(--shadow); }
  /* Keep the "current plan" label at full contrast — the old opacity fade made it unreadable. */
  .tier-card .tier-pick[disabled] { opacity: 1; cursor: default; box-shadow: none; color: var(--ink); font-weight: 700; }
  /* `flex: 0 0 auto` is load-bearing: this chip is a flex CHILD in both places it appears, and
     in `.ex-head` (a row) it sits next to the add-on volume line, which is long enough to shrink
     a default `flex-shrink: 1` chip to ~30px wide while `height` stays 46 — a squashed rectangle.
     The blog explainer never showed it only because it has no volume line to compete with. */
  .tier-ico {
    width: 46px; height: 46px; flex: 0 0 auto;
    border-radius: 13px; display: flex; align-items: center; justify-content: center;
    color: #fff; background: linear-gradient(135deg, var(--tier-a), var(--tier-b));
    box-shadow: 0 8px 18px -8px color-mix(in srgb, var(--tier-a) 75%, transparent);
    transition: transform .3s cubic-bezier(.22,.8,.3,1);
  }
  .tier-ico svg { width: 24px; height: 24px; }
  .tier-card:hover .tier-ico { transform: rotate(-6deg) scale(1.08); }
  .tier-name { font-size: 19px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
  .tier-price {
    font-size: 30px; font-weight: 800; letter-spacing: -.02em;
    background: linear-gradient(120deg, var(--tier-a), var(--tier-b)); -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  .tier-per { font-size: 13px; font-weight: 600; color: var(--muted); margin-left: 4px; -webkit-text-fill-color: var(--muted); }
  .tier-perks { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; flex: 1 1 auto; }
  .tier-perks li { position: relative; padding-left: 27px; font-size: 14px; line-height: 1.4; }
  .tier-perks li::before {
    position: absolute; left: 0; top: -1px; width: 19px; height: 19px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; line-height: 1;
  }
  .tier-perks li.ok { color: var(--ink-2); }
  .tier-perks li.ok::before { content: "✓"; color: var(--tier-a); background: color-mix(in srgb, var(--tier-a) 15%, transparent); }
  .tier-perks li.no { color: var(--muted-2); }
  .tier-perks li.no::before { content: "×"; color: var(--muted-2); background: color-mix(in srgb, var(--muted) 14%, transparent); }
  .tier-pick { width: 100%; justify-content: center; margin-top: 6px; }
  /* THE one filled button on the panel: the tier the client is about to order. Every pick
     button ships as a `.btn.secondary` outline and `.is-accent` moves between them (server:
     the tier_pick macro, live: 07-shop.js `render()`), so choosing Starter takes the fill
     OFF the featured card instead of lighting a second one — and the card the client already
     pays for never gets it at all. One class heavier than the base.css `.btn.secondary`
     rules it overrides, hover included (that one would otherwise repaint it white). */
  .tier-card .tier-pick.is-accent {
    background: linear-gradient(90deg, var(--tier-a), var(--tier-b));
    border-color: transparent; color: #fff;
    box-shadow: 0 8px 20px -8px color-mix(in srgb, var(--tier-a) 60%, transparent);
  }
  .tier-card .tier-pick.is-accent:hover:not(:disabled) {
    background: linear-gradient(90deg, var(--tier-b), var(--tier-a));
    border-color: transparent; color: #fff;
  }
  /* `.btn.secondary::after` kills the shine sweep — the accent is a primary button in all but
     class name, so it gets it back (and gives it up again with reduced motion, like .btn). */
  .tier-card .tier-pick.is-accent::after { display: block; }
  @media (prefers-reduced-motion: reduce) {
    .tier-card .tier-pick.is-accent::after { display: none; }
  }

  /* --- Entry tier's free first month (tier_card `free_month`) ---
     A badge alone next to a live price reads as decoration, so the PRICE carries the offer:
     the monthly amount struck through, 0 beside it, and one line saying when billing starts.
     The struck number drops the block's gradient text-fill for a flat colour — a
     transparent-on-gradient number with a rule through it is unreadable at 30px. `.tier-now`
     keeps `color: transparent` (inherited) so the parent's clipped gradient still paints it.
     Kolor to `--ink-2`, NIE `--muted`: przekreślona kwota jest połową oferty („zamiast 450 zł
     — 0 zł"), a w szarości `--muted` gasła obok wielkiego zera i klient nie widział, ile
     właściwie dostaje za darmo. Kreska idzie pełnym `--warn` (wcześniej 80% w przezroczystość,
     czyli jeszcze bledziej) i `skip-ink: none`, żeby była JEDNĄ ciągłą linią — przerwana na
     cyfrach czytała się jak artefakt renderowania, a nie jak przekreślenie. */
  .tier-price.is-free { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; }
  .tier-was {
    font-weight: 700; color: var(--ink-2); -webkit-text-fill-color: var(--ink-2);
    text-decoration: line-through; text-decoration-thickness: 2px;
    text-decoration-color: var(--warn); text-decoration-skip-ink: none;
  }
  .tier-price .tier-was { font-size: 19px; }
  .tier-price.is-free .tier-per { margin-left: 0; }
  .tier-free-note { font-size: 12.5px; line-height: 1.45; color: var(--ink-2); }
  /* Ten sam wiersz w kartach bez bezpłatnego miesiąca niesie zdanie o progu (§HTML). Jest to
     tekst opisowy, nie oferta, więc idzie w `--muted` — obok ceny nie może z nią konkurować. */
  .tier-free-note.is-desc { color: var(--muted); }
  /* Karty jako SUBGRID: ikona, nazwa, cena, notka, pigułka wolumenu, rozszerzenia, suma i
     przycisk siedzą w tych samych wierszach we WSZYSTKICH trzech kartach. Bez tego notka
     (w karcie 1 „pierwszy miesiąc gratis", w pozostałych zdanie o progu — teksty różnej
     długości) spychała u siebie resztę w dół, a cena w wariancie `is-free` jest
     trzywierszowa, więc rozjazd był podwójny. Wiersz zawsze ma wysokość najwyższej z trzech
     kart. Liczba dzieci karty (8) MUSI zgadzać się z liczbą wierszy; `.tier-badge` jest
     absolutny, więc nie jest itemem gridu i się nie liczy.
     `row-gap` na siatce zastępuje wewnętrzny `gap: 12px` karty.
     MIEJSCE TEGO BLOKU JEST CELOWE — stał wcześniej NAD `.tier-card`, więc reguła o tej samej
     specyficzności, dalej w pliku, cofała mu `display: grid`: karty zostawały flexem i
     rozjeżdżały się dokładnie tak, jak subgrid miał temu zapobiec. Media query nie podbija
     specyficzności — ten blok musi zostać PO nich. */
  @supports (grid-template-rows: subgrid) {
    @media (min-width: 901px) {
      .tier-grid { grid-template-rows: repeat(8, auto); row-gap: 12px; column-gap: 20px; }
      .tier-card { display: grid; grid-template-rows: subgrid; grid-row: 1 / -1; gap: 0; }
    }
  }
  .tier-total-value.is-free { display: inline-flex; align-items: baseline; gap: 7px; }
  .tier-total-value .tier-was { font-size: 16px; }
  /* The trial covers the add-ons too, so their rows are struck the same way. Stacked, not
     inline: the row price shares a grid track with the channel name, and "+150 zł 0 zł" on
     one nowrap line pushed the name column out of the card on the narrow breakpoint.
     Obie liczby stoją w rozmiarze CENY wiersza (16px), więc hierarchię niesie kolor i grubość
     (ink-2/700 „było" pod ink/800 „jest"), nie stopień pisma — to właśnie przekreślona kwota
     miała być wreszcie czytelna, a zdrobniona wracała tam, skąd ją wyciągnęliśmy.
     Przy dwóch liniach po 16px `gap: 1px` sklejał je w jedną pomyloną liczbę: stąd 3px i
     ciaśniejsza interlinia, żeby stos urósł o odstęp, a nie o światło wewnątrz linii.
     Grubość kreski zostaje dziedziczona (2px z `.tier-was`) — override na 1.5px był pisany
     pod 11px i przy 16px robił z przekreślenia włos. */
  .xrow-price.is-free {
    display: flex; flex-direction: column; align-items: flex-end;
    gap: 3px; line-height: 1.15;
  }
  .xrow-price .tier-was { font-size: 16px; }
  .xrow-now { font-size: 16px; font-weight: 800; color: var(--ink); }

  /* Volume is the ONLY thing that differs between base tiers, so it gets its own block
     rather than a bullet: the monthly article count leads, the cadence explains it. */
  .tier-volume {
    margin-top: 2px; padding: 12px 14px; border-radius: 13px; flex: 0 0 auto;
    background: color-mix(in srgb, var(--tier-a) 9%, transparent);
    border: 1px solid color-mix(in srgb, var(--tier-a) 22%, transparent);
    display: flex; flex-direction: column; gap: 3px;
  }
  .tier-volume-n { font-size: 15px; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
  /* --- What the package is made of: the blog row + the add-on checkboxes, in every card ---
     The pick is global (ticking one row ticks it in all three cards); what differs per card
     is the PRICE, because add-ons cost more on bigger tiers.
     This block must NOT be bottom-pinned. The cards are `align-items: stretch`, so they all
     take the tallest card's height; a `margin-top:auto` here collected every pixel of a
     card's leftover height into ONE gap — the one between the volume pill and the blog row.
     Cards whose extend block is shorter (no `.xrow-owned` line, because nothing in them is
     the client's current add-on) got a visibly bigger hole than the owned tier. The bottom
     alignment that was wanted belongs to `.tier-total` instead, which carries it now. */
  .tier-extend { padding-top: 6px; display: flex; flex-direction: column; gap: 8px; }
  /* "Rozszerz pakiet" — a header for the OPTIONAL rows only, hence below the blog row. */
  .tier-extend-h { margin-top: 2px; font-size: 11.5px; font-weight: 800; letter-spacing: .04em; color: var(--ink-2); }
  .xrow {
    display: grid; grid-template-columns: auto auto 1fr auto; align-items: center; gap: 9px;
    padding: 9px 11px; border-radius: 12px; cursor: pointer;
    border: 1px solid var(--line); background: transparent;
    transition: border-color .18s, background .18s, box-shadow .18s;
  }
  .xrow:hover { border-color: color-mix(in srgb, var(--ax) 45%, var(--line)); }
  .xrow.is-on { border-color: color-mix(in srgb, var(--ax) 55%, var(--line)); background: color-mix(in srgb, var(--ax) 8%, transparent); }
  /* `.is-owned` MARKS what the client already pays for — it does not lock the row. */
  .xrow--base { cursor: default; }
  .xrow[data-addon-row="blog"] { --ax: #289be5; }
  .xrow[data-addon-row="social"] { --ax: #e1306c; }
  .xrow[data-addon-row="video"] { --ax: #7c3aed; }
  /* The blog row is the package itself, not an extra: it sits ABOVE the "Rozszerz pakiet"
     header, and its price has no leading "+". */
  .xrow--base { margin-bottom: 2px; }
  /* Drawn by us, not by the platform. The native control paints a checked-but-DISABLED box
     as grey-on-grey (and browsers disagree on how grey), which made the permanently-ticked
     blog row read as unticked. Everything here — box, fill, tick — is our own CSS, so the
     locked-on rows look exactly as on as the ones the client just clicked. */
  .xrow-box {
    appearance: none; -webkit-appearance: none;
    display: block;   /* the static span is inline by default — it would ignore width/height */
    width: 18px; height: 18px; margin: 0; flex: 0 0 auto; cursor: inherit;
    border: 1.5px solid color-mix(in srgb, var(--ax) 40%, var(--line));
    border-radius: 6px; background: var(--card);
    background-repeat: no-repeat; background-position: center; background-size: 13px;
    /* No transition on the fill: a checkbox must read as on/off the instant it flips, and a
       transition that never finishes (background tab, reduced motion) leaves it mid-colour. */
  }
  /* `--static` is the blog row's tick: a span, permanently in the checked look (see the
     base_row macro for why it is not a disabled checkbox). */
  .xrow-box:checked, .xrow-box--static {
    background-color: var(--ax); border-color: var(--ax);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.4 8.4l3 3 6.2-6.2' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  .xrow-box:focus-visible { outline: 2px solid var(--ax); outline-offset: 2px; }
  .xrow-ico {
    width: 26px; height: 26px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
    color: #fff; background: var(--ax);
  }
  .xrow-ico svg { width: 15px; height: 15px; }
  .xrow-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .xrow-name { font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.2; }
  .xrow-vol { font-size: 11px; color: var(--muted); line-height: 1.2; }
  /* `letter-spacing: -.02em` jak przy pozostałych DUŻYCH liczbach karty (`.tier-price`,
     `.tier-total-value`): przy 16px/800 domyślny trekking rozpychał „+150 zł" w kolumnie,
     która jest `auto` — każdy odzyskany piksel wraca do nazwy (`1fr`), a to ona łamie się
     na dwie linie i podbija wysokość wiersza we WSZYSTKICH kartach (subgrid). */
  .xrow-price { text-align: right; font-size: 16px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); white-space: nowrap; line-height: 1.2; }
  .xrow-per { display: block; font-size: 10px; font-weight: 600; color: var(--muted); margin: 0; }
  /* What the client already pays for, and — once they untick it — that they are about to ask
     us to STOP. The drop marker is warn-coloured: it is the one state in this panel that
     takes something away, so it must not read like another neutral caption. */
  .xrow-owned, .xrow-drop {
    grid-column: 1 / -1; font-size: 10.5px; font-weight: 700; letter-spacing: .03em;
    text-transform: uppercase; color: var(--ax);
  }
  .xrow-drop { display: none; color: var(--warn); }
  .xrow.is-owned:not(.is-on) .xrow-owned { display: none; }
  .xrow.is-owned:not(.is-on) .xrow-drop { display: block; }
  .xrow.is-owned:not(.is-on) { border-color: color-mix(in srgb, var(--warn) 50%, var(--line)); }

  /* Per-card running total — base + whatever is ticked, at THIS tier's add-on prices.
     `margin-top:auto` pins the total + the button under it to the card's bottom edge, so the
     three cards' CTAs line up. Slack now pools directly above this rule instead of above the
     blog row, where it reads as breathing room rather than a hole in the card. */
  .tier-total {
    display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
    margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line);
  }
  .tier-total-label { font-size: 13px; font-weight: 700; color: var(--ink-2); margin-right: auto; }
  .tier-total-value {
    font-size: 22px; font-weight: 800; letter-spacing: -.02em;
    background: linear-gradient(120deg, var(--tier-a), var(--tier-b));
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }

  /* Picked state: the chosen tier must read as chosen at a glance — ring in the card's own
     gradient, filled button, and the label swaps "Wybieram" → "✓ Wybrany". */
  .pick-on { display: none; }
  .is-picked .tier-pick .pick-idle { display: none; }
  .is-picked .tier-pick .pick-on { display: inline; }
  /* The tier the client already pays for says so on its button instead of "Wybieram" — it is
     still clickable (that's how you keep the tier and add an add-on), the ✓ just tracks
     whether it is the picked one. MUST stay after the .is-picked rules: same specificity,
     later wins. */
  .pick-current, .tier-card.is-current .tier-pick .pick-idle,
  .tier-card.is-current .tier-pick .pick-on { display: none; }
  .tier-card.is-current .tier-pick .pick-current { display: inline; }
  .tier-card.is-current .tier-pick .pick-tick { display: none; }
  .tier-card.is-current.is-picked .tier-pick .pick-tick { display: inline; }
  .tier-card.is-picked {
    border-color: color-mix(in srgb, var(--tier-a) 62%, var(--line));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--tier-a) 50%, transparent), var(--shadow);
  }
  /* "Twój pakiet" is a STATUS, not an offer, so the tier the client already pays for gets a
     soft tint in its own colour instead of the accent's fill — a plain white button there
     read as a dead control, a filled one sold what they already have. It is the reason a
     client on a plan sees no filled button until they pick a DIFFERENT tier (`.is-accent`
     above, which this card never carries). */
  .tier-card.is-current .tier-pick {
    background: color-mix(in srgb, var(--tier-a) 12%, var(--card));
    border-color: color-mix(in srgb, var(--tier-a) 42%, var(--line));
    color: color-mix(in srgb, var(--tier-a) 65%, var(--ink));
  }
  .tier-card.is-current .tier-pick:hover:not(:disabled) {
    background: color-mix(in srgb, var(--tier-a) 20%, var(--card));
    border-color: color-mix(in srgb, var(--tier-a) 60%, var(--line));
    color: color-mix(in srgb, var(--tier-a) 65%, var(--ink));
  }

  /* --- "Co zawiera usługa?" — the capability copy, once, below the offer ---
     Three read-only explainer cards (base package + each add-on). No controls live here: the
     buying decision is entirely in the tier grid above. */
  .shop-explain { margin-top: 42px; }
  .explain-head { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; color: var(--ink); }
  .explain-head::before, .explain-head::after {
    content: ""; flex: 1 1 auto; height: 1px;
    background: linear-gradient(90deg, transparent, var(--line), transparent);
  }
  .explain-head span { font-size: 19px; font-weight: 800; letter-spacing: -.02em; white-space: nowrap; }
  .explain-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
  @media (max-width: 900px) { .explain-grid { grid-template-columns: 1fr; } }
  .ex-card {
    display: flex; flex-direction: column; gap: 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 18px;
    box-shadow: var(--shadow); padding: 22px 20px;
    transition: border-color .2s, box-shadow .2s;
  }
  .ex-card:hover { border-color: color-mix(in srgb, var(--tier-a) 40%, var(--line)); }
  .ex-head { display: flex; align-items: center; gap: 12px; }
  .ex-id { min-width: 0; }
  .ex-name {
    font-size: 17px; font-weight: 800; letter-spacing: -.01em;
    background: linear-gradient(120deg, var(--tier-a), var(--tier-b));
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  .ex-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
  .ex-card .tier-perks { gap: 9px; }
  .ex-card .tier-perks li { font-size: 13.5px; }
  /* Payoff line, split off the bullets by a rule: what the client GETS, not what we do. */
  .ex-foot {
    display: flex; align-items: center; gap: 12px; margin-top: auto; padding-top: 16px;
    border-top: 1px solid var(--line); font-size: 15px; font-weight: 700; line-height: 1.35;
    color: var(--ink-2);
  }
  .ex-foot-ico {
    width: 34px; height: 34px; border-radius: 10px; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    color: var(--tier-a); background: color-mix(in srgb, var(--tier-a) 13%, transparent);
  }
  .ex-foot-ico svg { width: 20px; height: 20px; }

  /* Explains a disabled send button (picked configuration == what the client already has),
     or — `.is-drop` — warns that the request also cancels something they pay for today. */
  .sum-note { margin: -4px 0 14px; font-size: 13px; line-height: 1.5; color: var(--muted); }
  .sum-note.is-drop {
    padding: 9px 12px; border-radius: 10px; font-weight: 600; color: var(--warn-ink);
    background: var(--warn-bg); border: 1px solid var(--warn-line);
  }
  .shop-form {
    margin: 26px auto 0; max-width: 560px; background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow); padding: 24px clamp(20px, 4vw, 32px);
  }
  .shop-form-title { margin: 0 0 14px; font-size: 17px; font-weight: 800; color: var(--ink); }
  /* PARAGON — co klient zamawia i za ile, powtórzone nad polami: karta, z której wybrał, jest
     dwa ekrany wyżej. Pozycje i sumę wpisuje 07-shop.js; w trybach bezpłatnych zostaje sam
     wiersz nagłówkowy (reszta ma `hidden`), bo nie ma czego wyceniać. */
  .shop-order {
    margin: 0 0 14px; padding: 13px 15px 12px; border-radius: 14px;
    background: color-mix(in srgb, var(--ink) 3.5%, var(--card));
    border: 1px solid var(--line);
  }
  .shop-order-head { display: flex; flex-direction: column; gap: 2px; }
  .shop-order-label {
    font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: var(--muted-2);
  }
  .shop-plan-value { font-size: 15px; font-weight: 800; color: var(--ink); line-height: 1.35; }
  .shop-plan-value.is-set { color: var(--brand-strong); }
  /* Free-first-month order: the line names the trial in its own text ("Starter (Bezpłatny
     test)"), so it only needs the ok tint the rest of the trial affordances carry — it must
     NOT stay brand-coloured like a paid pick. Overrides .is-set, so it comes after it. */
  .shop-plan-value.is-trial { color: var(--ok); }
  /* Opis wybranego progu — zdanie pod nazwą konfiguracji, nie druga nazwa: stonowany kolor i
     mniejszy stopień, żeby nie konkurował z `.shop-plan-value` ani z ceną w paragonie.
     `margin-top` zamiast `gap`, bo nagłówek trzyma etykietę i nazwę ciasno (gap: 2px). */
  .shop-plan-desc {
    margin: 5px 0 0; font-size: 12px; line-height: 1.5; font-weight: 500; color: var(--muted);
  }
  .shop-order-items {
    list-style: none; margin: 11px 0 0; padding: 11px 0 0; border-top: 1px solid var(--line);
    display: flex; flex-direction: column; gap: 9px;
  }
  .shop-order-item { display: flex; align-items: baseline; gap: 12px; }
  /* `display:flex` z reguł wyżej bije domyślne `[hidden]` przeglądarki — bez tego ukryte
     pozycje/suma (tryby bezpłatne) i „Co dalej?" (przed wysyłką) i tak by się rysowały. */
  .shop-order-items[hidden], .shop-order-total[hidden], .shop-next[hidden] { display: none; }
  .soi-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
  .soi-name { font-size: 13.5px; font-weight: 700; color: var(--ink); }
  .soi-vol { font-size: 11.5px; line-height: 1.45; color: var(--muted); }
  .soi-price { flex: 0 0 auto; font-size: 13.5px; font-weight: 700; color: var(--ink-2); white-space: nowrap; }
  .shop-order-total {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
  }
  .shop-order-total-label { font-size: 12.5px; font-weight: 700; color: var(--muted); }
  .shop-order-total-main { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
  .shop-order-total-value { font-size: 19px; font-weight: 900; color: var(--brand-strong); }
  /* Przekreślona kwota w paragonie — ta sama recepta co `.tier-was` na karcie (ink-2 + pełny
     `--warn` na kresce, ciągłej): stała tu w `--muted-2`, najjaśniejszej szarości w palecie,
     przy 13px i bez koloru kreski — czyli dokładnie w miejscu, w którym klient sprawdza, ile
     normalnie kosztuje to, co dostaje za 0 zł, kwota była praktycznie niewidoczna. */
  .shop-order-was {
    font-size: 13.5px; font-weight: 700; color: var(--ink-2);
    text-decoration: line-through; text-decoration-thickness: 2px;
    text-decoration-color: var(--warn); text-decoration-skip-ink: none;
  }
  .shop-order-per { font-size: 11.5px; font-weight: 600; color: var(--muted); }
  /* Bezpłatny miesiąc: pozycje zostają w swoich cenach (tyle kosztuje pakiet), zeruje się samo
     „Razem" — przekreślona kwota + 0 w tincie `--ok`, tak jak na karcie. */
  .shop-order-total.is-free .shop-order-total-value { color: var(--ok); }
  /* Zdanie pod sumą. Przy teście jest obietnicą („nic się samo nie pobierze") i nosi ten sam
     tint `--ok`, co wyzerowane „Razem" nad nim; przy płatnym zamówieniu to zwykła informacja
     proceduralna, więc `.is-plain` gasi zieleń — inaczej kwota do zapłaty dostawała pod spodem
     kolor, którym cała strona oznacza „za darmo". */
  .shop-order-note { margin: 9px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--ok); }
  .shop-order-note.is-plain { color: var(--muted); }
  /* "Co dalej?" — the mode's what-happens-next copy, shown only in the confirmation card after
     the form has been sent. A quiet brand-tinted note, not a warning: it reassures, so it must
     not borrow the amber/red of .sum-note.is-drop. */
  .shop-next {
    display: flex; gap: 10px; margin: 0; padding: 12px 14px; text-align: left;
    border-radius: 12px; background: var(--brand-ghost); border: 1px solid var(--brand-line);
  }
  .shop-next-ico { flex: 0 0 17px; width: 17px; height: 17px; margin-top: 1px; color: var(--brand-strong); }
  .shop-next-ico svg { width: 100%; height: 100%; display: block; }
  .shop-next-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .shop-next-title { font-size: 13px; font-weight: 800; color: var(--brand-strong); }
  .shop-next-text { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }
  .shop-form-actions { display: flex; justify-content: flex-end; margin-top: 16px; }
  .shop-form-actions .btn { min-width: 160px; justify-content: center; }
  /* Potwierdzenie wysyłki: ptaszek + jedno zdanie + przeniesiony tu blok „Co dalej?". */
  .shop-sent {
    display: flex; flex-direction: column; align-items: center; gap: 13px;
    text-align: center; padding: 10px 0 4px;
  }
  .shop-sent-ico {
    width: 46px; height: 46px; flex: 0 0 46px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent);
  }
  .shop-sent-ico svg { width: 26px; height: 26px; display: block; }
  .shop-sent-title { margin: 0; font-size: 16px; font-weight: 800; line-height: 1.45; color: var(--ink); }
  .shop-sent .shop-next { width: 100%; }

  .nav-btn.is-locked { color: var(--muted-2); opacity: .68; }
  .nav-btn.is-locked .nav-ico { color: var(--muted-2); }
  .nav-btn.is-locked:hover { opacity: 1; }
  .nav-btn[data-state="connect"] .nav-count, .nav-btn[data-state="locked"] .nav-count { display: none; }

  .locked-banner { display: flex; align-items: center; gap: 18px; padding: 20px 24px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
  .locked-banner .rp-ico { width: 52px; height: 52px; flex: 0 0 52px; border-radius: 15px; display: flex; align-items: center; justify-content: center; background: var(--brand-ghost); color: var(--brand-strong); }
  .locked-banner-main { flex: 1; min-width: 0; }
  .locked-banner-main h2 { margin: 0 0 3px; font-size: 17px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
  .locked-banner-main p { margin: 0; color: var(--muted); font-size: 14px; line-height: 1.5; }
  .locked-banner .btn { flex: 0 0 auto; }
  /* Slim banner above a day list of real drafts on an unconnected / out-of-package channel. */
  .channel-notice { margin-bottom: 16px; padding: 15px 20px; border-left: 3px solid var(--brand); }
  .channel-notice .rp-ico { width: 42px; height: 42px; flex: 0 0 42px; border-radius: 13px; }
  .channel-notice .rp-ico svg { width: 22px; height: 22px; }
  .channel-notice .locked-banner-main h2 { font-size: 15.5px; }
  .channel-notice .locked-banner-main p { font-size: 13.5px; }
  .locked-samples { columns: 2; column-gap: 22px; margin-top: 18px; }
  .social-card--sample, .social-card--sample * { cursor: default; }
  .social-card--sample .sc-media.single { background: var(--card-soft); }
  .social-card--sample .sc-media img { width: 100%; height: 100%; max-height: none; object-fit: cover; display: block; margin: 0; }
  .sample-media--1x1 { aspect-ratio: 1 / 1; }
  .sample-media--45 { aspect-ratio: 4 / 5; }
  @media (max-width: 620px) {
    .locked-samples { columns: 1; max-width: 420px; margin-inline: auto; }
    .locked-banner { flex-direction: column; align-items: flex-start; }
  }

  /* The reel layout itself stays: TikTok/YouTube verticals use it for their 9:16 media. */
  .sc-media.reel { aspect-ratio: 9 / 16; max-height: 600px; }
  .sc-media.reel video, .sc-media.reel img { width: 100%; height: 100%; max-height: none; object-fit: cover; }
  .sc-actions-reel {
    position: absolute; right: 10px; bottom: 16px; z-index: 3;
    display: flex; flex-direction: column; gap: 15px; align-items: center;
  }
  .sc-actions-reel .reel-act {
    width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    color: #fff; background: rgba(16, 18, 22, .34); backdrop-filter: blur(3px); box-shadow: 0 2px 8px rgba(0,0,0,.25);
  }
  .sc-actions-reel .reel-act svg { width: 22px; height: 22px; }

  @media (prefers-reduced-motion: reduce) { .nav-btn { transition: none; } }
  @media (max-width: 720px) {
    .subbar { grid-template-columns: 1fr; justify-items: center; gap: 10px; }
    .subbar-left, .subbar-center, .subbar-right { justify-self: center; }
    .subbar-left { justify-content: center; }
    /* Tabs stay one row; the plan group drops to its own row underneath (it is the only
       full-width flex child, so the tabs themselves only wrap if they outgrow the row —
       the ≤560px sizing below keeps them from doing that down to 320px). */
    .navbar { flex-wrap: wrap; }
    .nav-btn { padding: 14px 15px; white-space: nowrap; }
    .nav-plan { width: 100%; margin-left: 0; padding: 8px 0 10px; justify-content: flex-end; border-top: 1px solid var(--line-soft); }
    .daynav-label { min-width: 150px; padding: 8px 16px; }
  }

  .article-list { margin: 8px 0 0; }
  .article-list .post-article { margin-bottom: 22px; }

  /* ---- Widok kafelków -------------------------------------------------------
     Źródłem prawdy jest data-review-view na <html> (ustawiane przed pierwszym
     malowaniem w <head>, potem przez 02-main.js). Kafelek i karta są rodzeństwem
     w .article-list: dokładnie jedno z nich jest widoczne, a filtr statusu z
     render() dokłada do obu inline display:none — dlatego te reguły NIE używają
     !important i nie mogą go dostać. */
  .article-tile { display: none; }
  /* 2 kafelki w rzędzie: .wrap ma max 1040px (≈1000px treści), więc minmax(340px, 1fr)
     nigdy nie zmieści trzeciej kolumny, a poniżej ~700px sam schodzi do jednej. */
  :root[data-review-view="tiles"] .article-list { display: grid; gap: 20px; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }
  :root[data-review-view="tiles"] .article-list .post-article { display: none; margin-bottom: 0; }
  :root[data-review-view="tiles"] .article-tile { display: flex; }

  .article-tile {
    appearance: none; font-family: inherit; text-align: left; padding: 0; cursor: pointer;
    flex-direction: column; overflow: hidden;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
  }
  .article-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand-line); }
  .article-tile:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
  .at-cover { display: block; aspect-ratio: 16 / 9; background: var(--card-soft); overflow: hidden; }
  .at-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .at-cover.is-empty { background: var(--brand-grad-90); opacity: .18; }
  .at-body { display: flex; flex-direction: column; gap: 8px; padding: 16px 18px 18px; }
  .at-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .at-pill {
    font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
    padding: 3px 7px; border-radius: 6px; color: var(--warn-ink); background: color-mix(in srgb, var(--warn) 16%, transparent);
  }
  .at-pill.is-published { color: var(--ok); background: color-mix(in srgb, var(--ok) 15%, transparent); }
  .at-day { font-size: 11px; font-weight: 700; color: var(--muted-2); }
  .at-title {
    font-family: var(--serif); font-weight: 700; font-size: 19px; line-height: 1.26;
    letter-spacing: -.01em; color: var(--ink);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .at-dek {
    font-size: 13.5px; line-height: 1.5; color: var(--muted);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  }

  /* ---- Popup kafelka --------------------------------------------------------
     Karta zostaje w swoim miejscu w DOM i tylko wychodzi na position:fixed —
     nic nie jest przenoszone, więc ramka artykułu się nie przeładowuje, a
     otwarty edytor nie traci treści. Żaden przodek .post-article nie ma
     transform/filter, inaczej fixed liczyłby się względem niego. */
  .tile-modal-back { position: fixed; inset: 0; z-index: 118; background: rgba(10,16,28,.6); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
  .tile-modal-close {
    position: fixed; top: 14px; right: 16px; z-index: 121;
    appearance: none; border: 0; cursor: pointer; width: 38px; height: 38px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--card); color: var(--ink); box-shadow: var(--shadow);
  }
  .tile-modal-back[hidden], .tile-modal-close[hidden] { display: none; }
  .tile-modal-close svg { width: 17px; height: 17px; }
  /* Wyśrodkowanie przez auto-marginesy, NIGDY przez transform: .edit-menu jest
     position:fixed i liczone z getBoundingClientRect(), więc transform na karcie
     przestawiłby jego blok zawierający na kartę i wyrzucił menu poza ekran. */
  :root[data-review-view="tiles"] .article-list .post-article.is-modal {
    display: block; position: fixed; z-index: 119;
    top: 3vh; bottom: 3vh; left: 0; right: 0; margin: 0 auto;
    width: min(940px, 94vw); overflow: auto; -webkit-overflow-scrolling: touch;
    box-shadow: 0 30px 80px rgba(10,16,28,.4);
  }

  .post-note {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 15px; border-top: 1px solid var(--line-soft); background: var(--card-soft);
    font-size: 12.5px; line-height: 1.45; color: var(--muted);
  }
  .post-note .pn-ico { flex: 0 0 auto; color: var(--muted-2); margin-top: 1px; }
  .post-note .pn-ico svg { width: 15px; height: 15px; }
  .post-note a { color: var(--brand); font-weight: 700; word-break: break-word; }
  .post-note em { font-style: normal; font-weight: 700; color: var(--ink-2); }
  .post-note .pn-pending { font-weight: 600; }
  .post-note.is-pending { background: var(--warn-bg); border-top-color: var(--warn-line); color: var(--warn); }
  .post-note.is-pending .pn-ico { color: var(--warn); }
  .post-note.is-pending em { color: var(--warn-ink); }

  @media (max-width: 480px) {
    .btn { padding: 10px 14px; }
    .article-inner { padding-top: 30px; }
  }

  /* ── Phones ──────────────────────────────────────────────────────────────────
     Two things drive this block. (1) The sticky stack — banner + tab row + plan row
     + info bar — pins 350px of an 844px phone in its desktop sizing, so every card
     the client scrolls to lands underneath it; everything here shrinks that stack.
     (2) iOS Safari zooms the page in on focusing any field under 16px and never
     zooms back, so every editable control gets 16px. */
  @media (max-width: 560px) {
    .wrap { padding-left: 14px; padding-right: 14px; }
    .masthead-title { padding: 4px 14px 18px; }
    .masthead-title h1 { margin: 4px 0 10px; }
    .masthead-sub { font-size: 14px; }
    .masthead-title.split { display: block; }
    .plat-promo { text-align: left; margin-top: 12px; }
    .plat-promo .plat-links { justify-content: start; }

    /* Sticky stack, row by row. */
    .onb-banner { padding: 10px 14px; font-size: 12.5px; gap: 8px; }
    .onb-banner-cta, .test-cta, .demo-cta { padding: 7px 12px; font-size: 12.5px; }
    .navbar { padding: 0 8px; }
    .nav-btn { padding: 12px 10px; font-size: 14px; gap: 7px; }
    .nav-plan { padding: 6px 6px 9px; gap: 8px; }
    /* "Twój pakiet:" — the value next to it already says what this is. */
    .nav-plan-label { display: none; }
    .infobars .client-card { padding: 10px 14px; gap: 8px 18px; }
    .cc-label { font-size: 9.5px; }
    .cc-value, .cc-acct { font-size: 13.5px; }

    /* Touch targets: the desktop pills are 27–29px tall. */
    .seg-btn { padding: 9px 13px; }
    /* Widok list/kafelki: ikony niosą znaczenie, a etykieta + licznik + filtr statusu
       nie mieszczą się w jednym wierszu paska. Tytuł/aria zostają. */
    .view-seg .seg-label { display: none; }
    .view-seg .seg-btn { padding: 9px 11px; }
    .tile-modal-close { top: 8px; right: 10px; }
    :root[data-review-view="tiles"] .article-list .post-article.is-modal { top: 0; bottom: 0; width: 100vw; border-radius: 0; }
    .edit-corner { padding: 8px 12px; font-size: 13px; }
    .emoji-btn { width: 38px; height: 38px; }
    .tone-ctrls button { width: 32px; height: 32px; }

    .caption-input, .modal-input, .modal-textarea { font-size: 16px; }
    .modal { padding: 20px 18px 18px; }
  }
  @media (max-width: 420px) {
    /* Below this the three tab labels + counts no longer fit beside their icons, and a
       wrapped tab row costs more than the icons are worth. */
    .nav-btn .nav-ico { display: none; }
    .nav-btn { padding: 12px 8px; }
  }
