/* Paper / cutout.

   Craft-inspired: everything is a piece of paper laid on a warm ground. Depth
   comes from layered shadows rather than lines, so the palette carries no
   border colour at all. Where structure is still needed, it is an outline (a
   dashed cut line) or a shadow ring, never a border.

   The canvas rendering is deliberately untouched by this file. Slide colours,
   scrims and text are the user's content, not our chrome, and restyling them
   would change carousels people have already designed. */

:root{
    /* palette */
    --primary:#e74c3c; --secondary:#3498db; --accent:#f39c12;
    --bg:#f5f0e6; --surface:#fffdf8; --text:#2c3e50;
    --text-dim:#6b7b8c;          /* --text, lightened, for secondary copy */
    --ink:#ffffff;               /* type that sits on a colour fill */
    --ok:#2e9e6b; --warn:#f39c12; --err:#e74c3c;

    /* one cut, two shadows: a hard offset for the paper edge and a soft
       ambient for the lift off the page */
    --r:2px; --r-lg:2px;
    --cut:0 4px 0 rgba(44,62,80,.05), 0 4px 12px rgba(44,62,80,.10);
    --cut-sm:0 4px 0 rgba(44,62,80,.04), 0 4px 8px rgba(44,62,80,.08);
    --cut-lg:0 4px 0 rgba(44,62,80,.06), 0 4px 28px rgba(44,62,80,.14);
    --etch:inset 0 0 0 1px rgba(44,62,80,.10);   /* a scored line, not a border */

    /* Space reserved for ads. Narrow screens get a bottom banner (--ad-h),
       wide ones a right rail (--ad-w); never both. Every fixed overlay offsets
       by these, otherwise it would sit on top of the ad. */
    --ad-w:0px; --ad-h:56px;
  }
  @media(min-width:1280px){ :root{ --ad-w:180px; --ad-h:0px } }
  *{box-sizing:border-box; margin:0; padding:0}
  html,body{height:100%}
  body{
    background:var(--bg); color:var(--text);
    font-family:Inter,system-ui,sans-serif; font-size:15px; line-height:1.5;
    -webkit-font-smoothing:antialiased;
    padding-right:var(--ad-w);
    padding-bottom:var(--ad-h);
  }

  /* ---------- ads ----------
     Default is the mobile shape: a banner pinned to the bottom edge. */
  #adRail{
    display:flex; position:fixed; left:0; right:0; bottom:0; height:var(--ad-h);
    flex-direction:row; align-items:stretch; gap:8px; padding:4px 10px;
    background:var(--surface); box-shadow:0 -4px 12px rgba(44,62,80,.10);
    overflow:hidden; z-index:30;
  }
  /* Wide screens switch it to a right rail. Must come after the base rule
     above, or it loses the cascade. */
  @media(min-width:1280px){
    #adRail{
      top:0; left:auto; bottom:0; width:var(--ad-w); height:100dvh;
      flex-direction:column; padding:14px 8px;
      box-shadow:-4px 0 12px rgba(44,62,80,.10);
    }
  }
  #adRail .adUnit{display:block; width:100%; flex:1; min-height:0}
  #adRail .adNote{
    font-size:10px; color:var(--text-dim); letter-spacing:.04em;
    text-transform:uppercase; align-self:center; flex-shrink:0;
  }
  /* Stands in when no publisher id is configured, so the layout stays
     testable. AdSense does not serve on localhost either way. */
  #adRail .adPlaceholder{
    flex:1; min-width:0; outline:1.5px dashed rgba(44,62,80,.22); outline-offset:-2px;
    border-radius:var(--r);
    display:flex; align-items:center; justify-content:center; gap:6px;
    text-align:center; color:var(--text-dim); font-size:12px; padding:6px;
  }
  #adRail .adHint{display:none}
  @media(min-width:1280px){
    #adRail .adPlaceholder{flex-direction:column; font-size:13px; padding:12px}
    #adRail .adHint{display:block; font-size:11px; opacity:.8}
  }

  h1,h2,h3{font-family:Poppins,Inter,sans-serif; line-height:1.15; color:var(--text)}
  button{font:inherit; cursor:pointer; border:none; border-radius:var(--r); min-height:44px}
  button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible{
    outline:2px solid var(--secondary); outline-offset:2px;
  }
  input,select,textarea{
    font:inherit; color:var(--text); background:var(--surface);
    border:none; border-radius:var(--r); padding:10px 12px; width:100%;
    box-shadow:var(--etch);
  }
  input:hover,select:hover,textarea:hover{box-shadow:inset 0 0 0 1px rgba(44,62,80,.20)}
  label{display:block; font-size:13px; color:var(--text-dim); margin-bottom:6px}

  /* Buttons are cut paper: they lift off the page and press into it. */
  .btn{
    background:var(--surface); color:var(--text); padding:10px 16px;
    box-shadow:var(--cut-sm), var(--etch); transition:transform .08s, box-shadow .08s;
  }
  .btn:hover{box-shadow:var(--cut), inset 0 0 0 1px rgba(44,62,80,.18)}
  .btn:active{transform:translateY(2px); box-shadow:0 1px 0 rgba(44,62,80,.06), var(--etch)}
  .btn-primary{
    background:var(--primary); color:var(--ink); font-weight:600; padding:12px 22px;
    box-shadow:var(--cut); transition:transform .08s, box-shadow .08s, filter .12s;
  }
  .btn-primary:hover{filter:brightness(1.06); box-shadow:var(--cut-lg)}
  .btn-primary:active{transform:translateY(2px); box-shadow:0 1px 0 rgba(44,62,80,.10)}
  .btn-primary:disabled{opacity:.45; cursor:not-allowed; box-shadow:none; transform:none}
  .btn-ghost{background:transparent; color:var(--text-dim); padding:10px 14px}
  .btn-ghost:hover{color:var(--text); background:rgba(44,62,80,.06)}
  .btn-sm{min-height:36px; padding:6px 12px; font-size:13px}

  /* ---------- setup screen ---------- */
  #setup{max-width:680px; margin:0 auto; padding:48px 20px 80px}
  /* Also an <a> on the calendar and admin pages, where the link colour
     would otherwise turn "tiny" blue. The colour is set here so the mark
     looks the same whatever element carries it. */
  .wordmark{font-family:Poppins,Inter,sans-serif; font-weight:700; font-size:20px; letter-spacing:-.01em; color:var(--text); text-decoration:none}
  .wordmark em{font-style:normal; color:var(--primary)}
  #setup h1{font-size:clamp(30px,6vw,44px); font-weight:700; letter-spacing:-.02em; margin:34px 0 10px}
  #setup .sub{color:var(--text-dim); max-width:46ch; margin-bottom:34px}
  .drop{
    /* a dashed cut line, as an outline rather than a border */
    outline:2px dashed rgba(44,62,80,.22); outline-offset:-4px;
    border-radius:var(--r-lg); background:var(--surface);
    padding:36px 20px; text-align:center; cursor:pointer;
    box-shadow:var(--cut-sm); transition:outline-color .15s, box-shadow .15s;
    /* Own its top spacing rather than borrowing the margin-bottom of whatever
       happens to sit above it. It previously followed the intro paragraph and
       looked fine by accident; putting the connect panel in between left the
       two boxes touching. Collapses with the paragraph's larger margin, so the
       top of the page is unchanged. */
    margin-top:26px;
  }
  .drop:hover,.drop.over{outline-color:var(--primary); box-shadow:var(--cut)}
  .drop p{color:var(--text-dim); font-size:14px; margin-top:6px}
  .drop strong{font-weight:600; color:var(--text)}
  #thumbs{display:flex; flex-wrap:wrap; gap:10px; margin-top:14px}
  #thumbs .t{position:relative; width:72px; height:90px; border-radius:var(--r); overflow:hidden; box-shadow:var(--cut-sm)}
  #thumbs .t img{width:100%; height:100%; object-fit:cover; display:block}
  /* stays dark: it sits on a photograph, where contrast is the only thing
     keeping it legible */
  #thumbs .t button{
    position:absolute; top:4px; right:4px; width:24px; height:24px; min-height:0;
    border-radius:50%; background:rgba(44,62,80,.75); color:#fff; font-size:13px; line-height:1;
  }
  .field{margin-top:22px}
  .row2{display:grid; grid-template-columns:1fr 1fr; gap:14px}
  @media(max-width:560px){.row2{grid-template-columns:1fr}}
  #sampleWrap{display:none}
  #generateBtn{width:100%; margin-top:28px; font-size:16px}
  .note{font-size:13px; color:var(--text-dim); margin-top:12px; text-align:center}
  #logoStatus{
    display:none; margin-left:6px; padding:2px 8px; border-radius:999px;
    background:var(--ok); color:var(--ink); font-size:11px; font-weight:600;
  }
  #logoStatus.show{display:inline-block}

  /* ---------- account ---------- */
  .setupHead{display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap}
  .authBox{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
  .authWho{font-size:13px; color:var(--text-dim); max-width:16ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
  /* Calendar and Admin are links dressed as buttons. A button gets its box
     from the button rule above; an anchor gets nothing, so it sat on its
     text baseline a few pixels off the buttons beside it. Same box here. */
  .authBox a.btn-ghost{display:inline-flex; align-items:center; border-radius:var(--r); text-decoration:none; line-height:1}
  .authBox .btn-sm{line-height:1}
  .planBadge{
    font-size:11px; font-weight:600; letter-spacing:.02em; padding:2px 8px;
    border-radius:999px; background:var(--surface); color:var(--text-dim); box-shadow:var(--etch);
  }
  .planBadge.creator{background:var(--ok); color:var(--ink); box-shadow:none}
  .planBadge.admin{background:var(--secondary); color:var(--ink); box-shadow:none; text-decoration:none}
  a.planBadge.admin:hover{filter:brightness(1.08)}
  /* Creator-only controls the user cannot use yet: still visible, so the
     feature is discoverable, but clearly not available. */
  .locked{opacity:.55}
  .locked::after{content:" (Creator)"; font-size:11px; color:var(--primary)}

  /* ---------- loading ---------- */
  #loading{display:none; position:fixed; inset:0 var(--ad-w) var(--ad-h) 0; background:rgba(245,240,230,.94); z-index:50;
    flex-direction:column; align-items:center; justify-content:center; gap:18px; text-align:center; padding:20px}
  .spinner{width:44px; height:44px; border-radius:50%; border:3px solid rgba(44,62,80,.15);
    border-top-color:var(--primary); animation:spin .9s linear infinite}
  @keyframes spin{to{transform:rotate(360deg)}}
  @media(prefers-reduced-motion:reduce){.spinner{animation-duration:2.5s}}
  #loadingMsg{color:var(--text-dim); max-width:40ch}

  /* ---------- editor ---------- */
  #editor{display:none; height:calc(100dvh - var(--ad-h)); flex-direction:column}
  .topbar{
    display:flex; align-items:center; gap:12px; padding:10px 16px;
    background:var(--surface); box-shadow:0 4px 12px rgba(44,62,80,.10);
    flex-wrap:wrap; position:relative; z-index:2;
  }
  .topbar .grow{flex:1}
  .workspace{flex:1; display:flex; min-height:0}
  .rail{
    width:96px; background:var(--surface); box-shadow:4px 0 12px rgba(44,62,80,.08);
    overflow-y:auto; padding:12px 10px; display:flex; flex-direction:column; gap:10px;
    flex-shrink:0; position:relative; z-index:1;
  }
  .rail .thumb{
    position:relative; border-radius:var(--r); overflow:hidden; cursor:pointer;
    background:var(--bg); aspect-ratio:4/5; box-shadow:var(--cut-sm);
  }
  .rail .thumb:not(.addTile){cursor:grab}
  .rail .thumb:not(.addTile):active{cursor:grabbing}
  /* selection is a shadow ring, since the palette has no border colour */
  .rail .thumb.sel{box-shadow:0 0 0 3px var(--primary), var(--cut-sm)}
  .rail .thumb.dropTarget{box-shadow:0 0 0 3px var(--ok), var(--cut-sm)}
  .rail .thumb.addTile{
    display:flex; align-items:center; justify-content:center; font-size:26px;
    color:var(--text-dim); outline:1.5px dashed rgba(44,62,80,.22); outline-offset:-3px;
    background:transparent; box-shadow:none;
  }
  .rail .thumb.addTile:hover{outline-color:var(--primary); color:var(--primary)}
  .rail .thumb img{width:100%; height:100%; object-fit:cover; display:block; pointer-events:none}
  /* also over a photograph, so also stays dark */
  .rail .thumb .n{
    position:absolute; left:4px; top:4px; background:rgba(44,62,80,.78); color:#fff;
    font-size:12px; min-width:26px; height:24px; display:flex; align-items:center; justify-content:center;
    border-radius:var(--r); touch-action:none; cursor:grab;
  }
  #zipBar{
    display:none; position:fixed; left:calc(50% - var(--ad-w) / 2); bottom:calc(84px + var(--ad-h)); transform:translateX(-50%);
    background:var(--surface); border-radius:var(--r);
    padding:10px 12px; z-index:55; gap:10px; align-items:center; max-width:92vw;
    box-shadow:var(--cut-lg);
  }
  #zipBar.show{display:flex}
  #zipBar a{text-decoration:none; display:inline-flex; align-items:center; justify-content:center}
  .stage{flex:1; display:flex; align-items:center; justify-content:center; padding:18px; min-width:0; min-height:0; background:var(--bg)}
  #canvasWrap{width:100%; height:100%; display:flex; align-items:center; justify-content:center}
  /* the slide itself reads as the topmost sheet on the pile */
  #stageCanvas{
    display:block; touch-action:none; cursor:grab; max-width:100%; max-height:100%;
    width:auto; height:auto; border-radius:var(--r);
    box-shadow:0 4px 0 rgba(44,62,80,.06), 0 12px 32px rgba(44,62,80,.18);
  }
  #stageCanvas.dragging{cursor:grabbing}
  .inspector{
    width:300px; background:var(--surface); box-shadow:-4px 0 12px rgba(44,62,80,.08);
    overflow-y:auto; padding:18px 16px 40px; flex-shrink:0; position:relative; z-index:1;
  }
  .inspector h3{font-size:14px; margin:20px 0 10px; color:var(--text-dim); font-weight:600}
  .inspector h3:first-child{margin-top:0}
  .inspector .field{margin-top:12px}
  .swatches{display:flex; gap:8px}
  .swatch{width:34px; height:34px; min-height:0; border-radius:var(--r); box-shadow:var(--etch), var(--cut-sm)}
  .swatch.sel{box-shadow:0 0 0 3px var(--primary), var(--cut-sm)}
  .seg{display:flex; background:var(--bg); border-radius:var(--r); overflow:hidden; box-shadow:var(--etch)}
  .seg button{flex:1; min-height:38px; background:transparent; color:var(--text-dim); border-radius:0; font-size:13px}
  .seg button:hover{background:rgba(44,62,80,.05); color:var(--text)}
  .seg button.sel{background:var(--primary); color:var(--ink); font-weight:600}
  .slide-actions{display:flex; gap:8px; margin-top:14px; flex-wrap:wrap}
  input[type=range]{padding:0; height:34px; accent-color:var(--primary); background:transparent; box-shadow:none}
  input[type=range]:hover{box-shadow:none}
  input[type=color]{
    width:46px; height:38px; flex-shrink:0; padding:3px; cursor:pointer;
    background:var(--surface); border-radius:var(--r); box-shadow:var(--etch);
  }
  input[type=color]::-webkit-color-swatch-wrapper{padding:0}
  input[type=color]::-webkit-color-swatch{border:none; border-radius:1px}
  #bgHex{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; text-transform:lowercase}

  /* captions drawer */
  #captionsDrawer{
    display:none; position:fixed; inset:auto var(--ad-w) var(--ad-h) 0; max-height:70dvh; overflow-y:auto;
    background:var(--surface); border-radius:var(--r-lg) var(--r-lg) 0 0;
    padding:22px 20px 40px; z-index:40; box-shadow:0 -10px 40px rgba(44,62,80,.20);
  }
  #captionsDrawer .cap{border-radius:var(--r); padding:14px; margin-top:12px; background:var(--bg); box-shadow:var(--cut-sm)}
  #captionsDrawer .cap .head{display:flex; align-items:center; justify-content:space-between; margin-bottom:8px}
  #captionsDrawer .cap .head b{font-size:14px}
  #captionsDrawer .cap p{font-size:14px; color:var(--text); white-space:pre-wrap}
  #captionsDrawer .cap .tags{font-size:13px; color:var(--secondary); margin-top:8px}

  /* save one by one */
  #saveModal{display:none; position:fixed; inset:0 var(--ad-w) var(--ad-h) 0; z-index:45; background:rgba(245,240,230,.97); overflow-y:auto; padding:18px 16px 70px}
  #saveModal .inner{max-width:560px; margin:0 auto}
  #saveModal .inner img{width:100%; border-radius:var(--r); margin-top:16px; display:block; box-shadow:var(--cut)}
  #saveModal .hint{color:var(--text-dim); font-size:14px; margin-top:8px}

  /* toast */
  #toast{
    position:fixed; left:calc(50% - var(--ad-w) / 2); bottom:calc(26px + var(--ad-h)); transform:translateX(-50%) translateY(20px);
    background:var(--text); color:var(--surface);
    padding:12px 18px; border-radius:var(--r); opacity:0; pointer-events:none;
    transition:opacity .2s, transform .2s; z-index:60; max-width:90vw; text-align:center;
    box-shadow:var(--cut-lg);
  }
  #toast.show{opacity:1; transform:translateX(-50%) translateY(0)}
  #toast.err{background:var(--err); color:var(--ink)}
  #toast.top{bottom:auto; top:14px; transform:translateX(-50%) translateY(-20px)}
  #toast.top.show{transform:translateX(-50%) translateY(0)}

  @media(max-width:820px){
    .workspace{flex-direction:column; overflow-y:auto}
    .rail{width:100%; flex-direction:row; overflow-x:auto; overflow-y:hidden;
      box-shadow:0 4px 12px rgba(44,62,80,.08)}
    .rail .thumb{width:64px; flex-shrink:0}
    .stage{padding:12px; height:54dvh; min-height:300px; flex:none}
    .inspector{width:100%; box-shadow:0 -4px 12px rgba(44,62,80,.08)}
  }
  .connectNote{font-size:12px; color:var(--text-dim)}

  /* ---------- connected accounts (setup screen) ---------- */
  .connectHint{font-size:11px; color:var(--primary); margin-left:6px}
  .connectPanel{display:flex; flex-direction:column; gap:8px}
  .connectPanel .row{
    display:flex; align-items:center; gap:10px; flex-wrap:wrap;
    background:var(--surface); border-radius:var(--r); padding:10px 12px;
    box-shadow:var(--cut-sm);
  }
  .connectPanel .name{font-size:14px; min-width:82px; font-weight:600}
  .connectPanel .state{font-size:12px; color:var(--text-dim); flex:1; min-width:120px}
  .connectPanel .state.on{color:var(--ok)}
  .connectPanel .row.soon{opacity:.6; box-shadow:var(--etch)}
  .warnBox{
    border-radius:var(--r); padding:10px 12px;
    font-size:13px; color:var(--text); background:rgba(243,156,18,.14);
    box-shadow:inset 0 0 0 1px rgba(243,156,18,.45);
  }

  /* Creator-only sections are removed for everyone else, not merely dimmed.
     Needs !important because these elements carry their own display values. */
  [hidden]{display:none !important}

  /* Creator pays instead of watching ads, so the rail is not merely empty: the
     space reserved for it collapses too. Without this the layout still held a
     180px gutter on desktop (or a 56px strip on mobile) for an ad that was
     never going to arrive. Higher specificity than the :root rules above, so
     it wins over the breakpoint that sets --ad-w. */
  :root.noAds{ --ad-w:0px; --ad-h:0px }
  :root.noAds #adRail{ display:none }

/* Legal links at the foot of the setup screen. Platform reviewers check that
   a privacy policy is reachable from inside the app, and anyone wondering
   what happens to their photos looks here first. */
.legal{
  margin-top:28px; padding-top:18px; display:flex; gap:18px; flex-wrap:wrap;
  border-top:1px solid rgba(44,62,80,.10);
}
.legal a{ color:var(--text-dim); font-size:13px; text-decoration:none }
.legal a:hover{ color:var(--primary); text-decoration:underline }

/* Content calendar page. Same shell as the setup screen, wider for the grid. */
#calendarShell{max-width:960px; margin:0 auto; padding:48px 20px 80px}
#calendarShell h1{font-size:clamp(28px,5vw,38px); font-weight:700; letter-spacing:-.02em; margin:34px 0 10px}
#calendarShell .sub{color:var(--text-dim); max-width:52ch; margin-bottom:28px}

.calList{margin-top:26px}
.calList h2, .calMonth h2{font-size:18px; margin:0 0 10px}
.calCount{display:inline-block; min-width:22px; padding:1px 7px; margin-left:4px; border-radius:999px;
  background:var(--bg); color:var(--text-dim); font-size:12px; font-weight:600; text-align:center; box-shadow:var(--etch)}
.calRow{
  display:flex; gap:12px; align-items:flex-start; padding:12px 14px; margin-top:8px;
  background:var(--surface); border-radius:var(--r); box-shadow:var(--cut-sm);
}
.calRow .calDot{margin-top:6px}
.calRowMain{flex:1; min-width:0}
.calRowTop{display:flex; gap:6px; align-items:baseline; flex-wrap:wrap; font-size:14px}
.calRowAcct{color:var(--text-dim)}
.calRowWhen{margin-left:auto; color:var(--text-dim); font-size:13px; white-space:nowrap}
.calRowCap{font-size:13px; margin-top:4px; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical}
.calRowStatus{font-size:12px; color:var(--text-dim); margin-top:6px}
.calRow.st-failed .calRowStatus, .calRow.st-needs_reconnect .calRowStatus{color:var(--err)}
.calRow.st-published .calRowStatus{color:var(--ok)}

.calMonth{margin-top:34px}
.calHead{display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap}
.calNav{display:flex; gap:8px; flex-wrap:wrap}
.calGrid{display:grid; grid-template-columns:repeat(7, minmax(0,1fr)); gap:6px; margin-top:14px}
.calDow{font-size:12px; color:var(--text-dim); text-align:center; padding:4px 0}
.calDay{
  min-height:92px; background:var(--bg); border-radius:var(--r); padding:6px;
  box-shadow:var(--etch); display:flex; flex-direction:column; gap:4px;
}
.calDay.blank{background:transparent; box-shadow:none}
.calDay.today{box-shadow:inset 0 0 0 2px var(--primary)}
.calNum{font-size:12px; color:var(--text-dim)}
.calDay.today .calNum{color:var(--primary); font-weight:600}
.calChip{
  display:flex; align-items:center; gap:5px; width:100%; text-align:left;
  background:var(--surface); border-radius:var(--r); padding:4px 6px; min-height:0;
  font-size:11px; line-height:1.3; box-shadow:var(--cut-sm); color:var(--text); cursor:pointer;
}
.calChip:hover{box-shadow:var(--cut)}
.calDot{width:8px; height:8px; border-radius:50%; background:var(--text-dim); flex-shrink:0}
.st-published .calDot{background:var(--ok)}
.st-failed .calDot{background:var(--err)}
.st-needs_reconnect .calDot{background:var(--warn)}
.st-publishing .calDot{background:var(--secondary); animation:calPulse 1s infinite}
@keyframes calPulse{50%{opacity:.3}}
.calGlyph{font-weight:700; font-size:10px; color:var(--text-dim); flex-shrink:0}
.calTxt{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.calDetail{margin-top:14px; padding:14px; background:var(--bg); border-radius:var(--r); box-shadow:var(--etch)}
.calDetail h3{font-size:15px; margin:0 0 4px}
.calCaption{font-size:13px; white-space:pre-wrap; margin:8px 0}
.calActions{display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:6px}
.calActions input[type=datetime-local]{min-height:34px; padding:4px 8px; font-size:13px; width:auto}
@media(max-width:720px){
  .calDay{min-height:64px}
  .calTxt{display:none}
  .calRowWhen{margin-left:0; width:100%}
}

/* Admin dashboard. Same shell as the calendar, wider for the panels. */
#adminShell{max-width:1180px; margin:0 auto; padding:48px 20px 80px}
#adminShell h1{font-size:clamp(28px,5vw,38px); font-weight:700; letter-spacing:-.02em; margin:34px 0 10px}
#adminShell .sub{color:var(--text-dim); max-width:52ch; margin-bottom:22px}
.adminBar{display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:18px}
.ranges{display:flex; gap:6px}
.ranges .btn.on{background:var(--text); color:var(--surface)}
.linkBtn{background:none; border:0; padding:0; color:var(--primary); cursor:pointer; font:inherit; font-size:inherit}
.kpis{display:grid; grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); gap:12px; margin-bottom:22px}
.kpi{background:var(--surface); box-shadow:var(--cut); padding:16px 18px; border-radius:2px}
.kpi .kv{font-family:"Poppins", system-ui, sans-serif; font-size:26px; font-weight:700; letter-spacing:-.02em; line-height:1.1}
.kpi .kl{color:var(--text-dim); font-size:12px; letter-spacing:.04em; text-transform:uppercase; margin-top:6px}
.kpi .ks{color:var(--text-dim); font-size:12px; margin-top:4px}
.kpi .dot{display:inline-block; width:10px; height:10px; border-radius:50%; margin-right:8px; vertical-align:middle; background:var(--text-dim)}
.kpi .dot.ok{background:var(--ok)} .kpi .dot.warn{background:var(--warn)} .kpi .dot.err{background:var(--err)}
.panels{display:grid; grid-template-columns:repeat(auto-fit, minmax(340px, 1fr)); gap:14px}
.panel{background:var(--surface); box-shadow:var(--cut); padding:16px 18px 14px; border-radius:2px; min-width:0}
.panel.wide{grid-column:1 / -1}
.panel h2{font-size:15px; margin:0 0 10px}
.chart{width:100%; height:auto; display:block}
.chart .grid{stroke:rgba(44,62,80,.10); stroke-width:1}
.chart .tick{font-size:11px; fill:var(--text-dim); font-family:"Inter", system-ui, sans-serif}
.legend{display:flex; gap:14px; flex-wrap:wrap; margin-top:6px; font-size:12px; color:var(--text-dim)}
.legend i{display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:6px; vertical-align:-1px}
.ranked{list-style:none; margin:0; padding:0; display:grid; gap:6px}
.ranked li{display:grid; grid-template-columns:minmax(0,1fr) 120px 70px; align-items:center; gap:10px; font-size:13px}
.ranked .rl{white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.ranked .rb{height:8px; background:var(--bg); border-radius:999px; overflow:hidden}
.ranked .rb i{display:block; height:100%; background:var(--secondary)}
.ranked .rn{text-align:right; font-variant-numeric:tabular-nums}
.ranked .rn small{color:var(--text-dim); margin-left:4px}
.tblWrap{overflow-x:auto}
.tbl{width:100%; border-collapse:collapse; font-size:13px}
.tbl th{text-align:left; color:var(--text-dim); font-weight:500; font-size:12px; padding:4px 8px 6px; border-bottom:1px solid rgba(44,62,80,.10)}
.tbl td{padding:6px 8px; border-bottom:1px solid rgba(44,62,80,.06); white-space:nowrap}
.tbl td.r, .tbl th:not(:first-child){text-align:right; font-variant-numeric:tabular-nums}
.tbl small{color:var(--text-dim); margin-left:4px}
.st{display:inline-block; padding:1px 8px; border-radius:999px; background:var(--bg); font-size:12px}
.st.st-published, .st.st-active{color:var(--ok)}
.st.st-failed, .st.st-revoked{color:var(--err)}
.st.st-needs_reconnect{color:var(--warn)}
.userFilter{width:100%; max-width:320px; margin-bottom:10px; min-height:36px; padding:6px 10px; font-size:13px}
.st.st-free{color:var(--text-dim)}
.facts{display:grid; grid-template-columns:auto 1fr; gap:6px 16px; margin:0; font-size:13px}
.facts dt{color:var(--text-dim)} .facts dd{margin:0}
@media (max-width:600px){ .ranked li{grid-template-columns:minmax(0,1fr) 70px 60px} }
