/**
 * site-cards.css — the "your things" CARD GRID.
 *
 * The card layout from My websites, as a component: a picture of the design,
 * a status pip, a name, a progress bar, and the one action that continues the
 * work. Opted into with `.st-grid` on a container.
 *
 * ── Why it moved out of launch-studio.css ───────────────────────────────
 * Alex, 2026-08-01, on the Courses list: "the layout of how each course is
 * sitting here should be similar to how the website is looking, so that in
 * little panels you can have the thumbnail of the actual design." And before
 * that, as a standing instruction: "You shouldn't be rebuilding anything new
 * really. The whole UI should match or almost be taken as components from the
 * website builder."
 *
 * Every rule here was scoped to `#page-launch-sites`, so a second surface
 * could only have them by growing its own copy. Two copies of a card is how
 * two products stop looking like one product, and it is the exact thing the
 * instruction above is against.
 *
 * ── Scoped to a class, not global ───────────────────────────────────────
 * `.st-grid` rather than bare `.st-card`, for the reason the wizard-shell
 * extraction found the hard way: an unscoped move hands these rules to any
 * page that happens to share a class name, and the surprises show up on
 * screens nobody edited. A consumer opts in; nothing is opted in by accident.
 *
 * The move trades an id for a class, which LOWERS specificity from (1,1,0) to
 * (0,2,0) — anything that used to lose to these rules can now win.
 * tests/browser/site-cards-css.browser.js renders the real card markup against
 * the stylesheets as they were before the move and as they are now, and diffs
 * every property that decides what a card looks like.
 *
 * NOT here: `#page-launch-sites .topbar` / `.crumbs`. That is the page's own
 * chrome rather than the card's, and it stays where it is.
 */

.st-grid .st-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 22px; }
.st-grid .st-head h1 { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 32px; margin: 0; letter-spacing: -0.02em; }
.st-grid .st-head .sub { color: var(--text-2); font-size: 14.5px; margin-top: 6px; }
.st-grid .st-head .sub b { color: var(--text); font-weight: 600; }
/* 48px, not 40. CODING-STANDARDS: "Minimum touch target: 48px. No exceptions."
   Measured at 40px on 2026-08-02 when this button moved into the courses
   control strip and the strip's own touch-target check caught it. It was the
   same 40px on My websites, where nothing was measuring — a primary call to
   action under the minimum on both products. Raised in the component, so both
   get it. */
.st-grid .st-add { background: var(--accent); color: #fff; border: none; border-radius: 11px; padding: 0 20px; min-height: 48px; font-size: 14px; font-weight: 600; display: inline-flex; align-items: center; gap: 8px; box-shadow: 0 10px 24px -10px rgba(106,76,241,0.6); white-space: nowrap; cursor: pointer; }
.st-grid .st-add:hover { background: var(--accent-deep); }
.st-grid .st-add svg { width: 15px; height: 15px; }
.st-grid .st-sites { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.st-grid .st-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; display: flex; flex-direction: column; transition: border-color .15s, box-shadow .15s, transform .15s; }
.st-grid .st-card:hover { border-color: var(--accent-2, var(--accent)); box-shadow: 0 26px 56px -40px rgba(106,76,241,0.45); transform: translateY(-2px); }
.st-grid .st-shot { aspect-ratio: 16/9; position: relative; background: var(--surface-3); overflow: hidden; }
.st-grid .st-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.st-grid .st-shot .ph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--text-4); font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 22px; background: linear-gradient(135deg, var(--surface-2), var(--surface-3)); }
.st-grid .st-shot .status { position: absolute; top: 12px; left: 12px; font-family: "Inter", sans-serif; font-size: 11px; font-weight: 600; padding: 4px 11px; border-radius: 999px; display: inline-flex; align-items: center; gap: 6px; z-index: 2; }
.st-grid .st-shot .status .d { width: 7px; height: 7px; border-radius: 50%; }
.st-grid .st-shot .status.live { background: #dcefe2; color: #1c7a4a; } .st-grid .st-shot .status.live .d { background: #1c7a4a; }
.st-grid .st-shot .status.prog { background: var(--accent-soft); color: var(--accent-deep); } .st-grid .st-shot .status.prog .d { background: var(--accent); }
.st-grid .st-shot .st-del { position: absolute; top: 10px; right: 10px; z-index: 3; width: 30px; height: 30px; border-radius: 8px; border: none; background: rgba(17,16,34,0.55); color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transition: opacity .15s ease, background .15s ease; }
.st-grid .st-card:hover .st-del, .st-grid .st-del:focus-visible { opacity: 1; }
.st-grid .st-shot .st-del:hover { background: #c0392b; }
.st-grid .st-shot .st-del svg { width: 15px; height: 15px; }
@media (hover: none) { .st-grid .st-shot .st-del { opacity: 1; } }
.st-grid .st-cbody { padding: 16px 18px 18px; flex: 1; display: flex; flex-direction: column; }
.st-grid .st-name { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 17px; letter-spacing: -0.01em; }
.st-grid .st-url { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--text-3); margin-top: 3px; }
.st-grid .st-prog { margin-top: 12px; }
.st-grid .st-prog .l { font-size: 12px; color: var(--text-3); display: flex; justify-content: space-between; margin-bottom: 5px; }
.st-grid .st-prog .l b { color: var(--accent-deep); font-weight: 600; }
.st-grid .st-prog .bar { height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.st-grid .st-prog .bar i { display: block; height: 100%; background: var(--accent); border-radius: 3px; transition: width .4s; }
/* §COMMUNITY-TIDY.6 — his words: the Manage / Continue setup buttons "should
   always be aligned. It shouldn't be wonky." The card body is a flex column,
   so the actions row pins to the FOOT: every card's button lines up across
   the row however much text sits above it. */
.st-grid .st-acts { display: flex; gap: 8px; margin-top: auto; padding-top: 16px; }
.st-grid .st-acts button, .st-grid .st-acts a { border-radius: 9px; padding: 10px 14px; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer; border: none; text-decoration: none; }
.st-grid .st-acts .primary { background: var(--accent); color: #fff; flex: 1; }
.st-grid .st-acts .primary:hover { background: var(--accent-deep); }
.st-grid .st-acts .primary svg { width: 13px; height: 13px; }
.st-grid .st-acts .ghost { background: var(--surface); color: var(--text-2); border: 1px solid var(--border); }
.st-grid .st-acts .ghost:hover { background: var(--surface-2); color: var(--text); }
.st-grid .st-acts .ghost svg { width: 14px; height: 14px; }
.st-grid .st-addcard { border: 1.5px dashed var(--border-strong); border-radius: var(--radius-lg); background: var(--surface-2); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 28px; min-height: 280px; color: var(--text-2); transition: border-color .15s, background .15s; cursor: pointer; }
.st-grid .st-addcard:hover { border-color: var(--accent-2, var(--accent)); background: var(--accent-softer, var(--accent-soft)); }
.st-grid .st-addcard .pl { width: 50px; height: 50px; border-radius: 14px; background: var(--surface); border: 1px solid var(--border); color: var(--accent); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.st-grid .st-addcard .pl svg { width: 24px; height: 24px; }
.st-grid .st-addcard .t { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 16px; color: var(--text); }
.st-grid .st-addcard .d { font-size: 13px; margin-top: 5px; max-width: 200px; line-height: 1.45; }
.st-grid .st-addcard .go { margin-top: 14px; font-size: 13px; font-weight: 600; color: var(--accent); display: inline-flex; align-items: center; gap: 6px; }
.st-grid .st-addcard .go svg { width: 14px; height: 14px; }
.st-grid .st-empty { text-align: center; padding: 60px 24px; }
.st-grid .st-empty .ic { width: 76px; height: 76px; border-radius: 20px; background: var(--accent-soft); color: var(--accent-deep); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 22px; }
.st-grid .st-empty .ic svg { width: 38px; height: 38px; }
.st-grid .st-empty h2 { font-family: "Bricolage Grotesque", sans-serif; font-weight: 800; font-size: 28px; margin: 0 0 10px; letter-spacing: -0.02em; }
.st-grid .st-empty p { color: var(--text-2); font-size: 15.5px; margin: 0 auto 24px; max-width: 480px; line-height: 1.55; }
.st-grid .st-empty p b { color: var(--text); font-weight: 600; }
.st-grid .st-empty .big { background: var(--accent); color: #fff; border: none; border-radius: 13px; padding: 15px 28px; font-size: 15.5px; font-weight: 700; display: inline-flex; align-items: center; gap: 10px; box-shadow: 0 14px 30px -12px rgba(106,76,241,0.6); cursor: pointer; }
.st-grid .st-empty .big:hover { background: var(--accent-deep); }
.st-grid .st-empty .big svg { width: 17px; height: 17px; }
.st-grid .st-empty .note { margin-top: 16px; font-size: 13px; color: var(--text-3); }
@media (max-width: 680px) { .st-grid .st-head { flex-direction: column; align-items: flex-start; } .st-grid .st-head h1 { font-size: 26px; } }

/* ══════════════════════════════════════════════════════════════════════
   ORDER AND SHAPE — the toolbar above the grid (2026-08-02)

   Alex: "in the courses area you should be able to sort by alphabet up or
   down, age, like most recent, and also you should be able to flip between
   rows or tiles."

   ⚠️ Honest note, because the standing instruction is to repurpose rather than
   rebuild: THIS DID NOT EXIST ANYWHERE. My websites has no sort and no view
   switch either — it renders whatever order the API returned, as tiles, full
   stop. So there was nothing to take. It is built HERE, in the shared card
   component, rather than privately in the Courses list, so My websites can
   have it by rendering one more element — which is the difference between
   this and the next lookalike.

   Rows are the same cards, turned on their side: the picture becomes a
   thumbnail at a fixed width and the body runs beside it. No second card
   markup, so nothing can drift between the two views.
   ══════════════════════════════════════════════════════════════════════ */

/* One right-aligned strip. `margin-left: auto` on the first child pushes the
   whole cluster right rather than each control finding its own edge — which is
   what the old `.sp` spacer did, and why Sort and the view switch ended up at
   opposite ends of the page with a gulf between them. */
.st-grid .st-tools {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  justify-content: flex-end; margin: 0 0 16px;
}
.st-grid .st-tools .st-add { margin-left: 4px; }

/* QUIET by default. Alex: "it doesn't need to be so dominant on the page."
   A sort control is a secondary thing — it carries no border until you go near
   it, and its type is the muted grey the rest of the page uses for metadata. */
.st-grid .st-sort {
  font: inherit; font-size: 13px; color: var(--text-2); background: transparent;
  border: 1px solid transparent; border-radius: 10px; padding: 0 30px 0 10px;
  /* 48px, the house minimum for anything a thumb has to hit — CODING-STANDARDS
     "Minimum touch target: 48px. No exceptions." The view switch beside it is
     built to the same height so the pair reads as one control strip. */
  height: 48px; cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237c7a8f' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center; background-size: 13px;
  transition: border-color .12s, background-color .12s, color .12s;
}
.st-grid .st-sort:hover { border-color: var(--border); background-color: var(--surface); color: var(--text); }
.st-grid .st-sort:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.st-grid .st-view {
  display: inline-flex; background: transparent; border: 1px solid var(--border);
  border-radius: 10px; overflow: hidden;
}
.st-grid .st-view button {
  border: none; background: transparent; color: var(--text-3); cursor: pointer;
  width: 48px; height: 48px;
  display: inline-flex; align-items: center; justify-content: center;
}
.st-grid .st-view button + button { border-left: 1px solid var(--border); }
.st-grid .st-view button svg { width: 17px; height: 17px; }
.st-grid .st-view button:hover { color: var(--text); }
.st-grid .st-view button.on { background: var(--surface); color: var(--accent-deep); box-shadow: 0 1px 3px rgba(17,16,34,0.10); }

/* ── Rows: the same card, on its side ─────────────────────────────────── */
.st-grid .st-sites.is-rows { grid-template-columns: 1fr; gap: 10px; }
.st-grid .st-sites.is-rows .st-card { flex-direction: row; align-items: stretch; }
.st-grid .st-sites.is-rows .st-card:hover { transform: none; }
/* The picture keeps its 16/9, so every row is the same height. Letting it size
   to the body instead gave a ragged list — a course with no lessons ended up
   two thirds the height of one mid-build. */
.st-grid .st-sites.is-rows .st-shot { width: 180px; flex: none; }
.st-grid .st-sites.is-rows .st-cbody { flex-direction: row; align-items: center; gap: 20px; padding: 14px 18px; }
.st-grid .st-sites.is-rows .st-cbody > .st-name { flex: 1 1 auto; min-width: 0; }
/* The mono sub-line moves BESIDE the name rather than being hidden. It carries
   the design slug or the lesson count, which is most of what tells one row
   from another once the pictures are small. */
.st-grid .st-sites.is-rows .st-url { flex: none; margin-top: 0; }
.st-grid .st-sites.is-rows .st-prog { margin-top: 0; width: 180px; flex: none; }
.st-grid .st-sites.is-rows .st-acts { margin-top: 0; flex: none; }
.st-grid .st-sites.is-rows .st-acts .primary { flex: none; }
/* The add-card is a tile-shaped invitation; as a row it is just a thin strip. */
.st-grid .st-sites.is-rows .st-addcard { min-height: 0; padding: 18px; flex-direction: row; gap: 14px; text-align: left; }
.st-grid .st-sites.is-rows .st-addcard .pl { margin-bottom: 0; width: 40px; height: 40px; }
.st-grid .st-sites.is-rows .st-addcard .d { display: none; }
.st-grid .st-sites.is-rows .st-addcard .go { margin-top: 0; margin-left: auto; }

/* A phone is one column wide either way, so rows collapse back to the card
   shape rather than squeezing four things onto a 375px line. */
@media (max-width: 700px) {
  .st-grid .st-sites.is-rows .st-card { flex-direction: column; }
  .st-grid .st-sites.is-rows .st-shot { width: auto; aspect-ratio: 16/9; }
  .st-grid .st-sites.is-rows .st-cbody { flex-direction: column; align-items: stretch; gap: 0; padding: 16px 18px 18px; }
  .st-grid .st-sites.is-rows .st-url { position: static; }
  .st-grid .st-sites.is-rows .st-prog { width: auto; margin-top: 12px; }
  .st-grid .st-sites.is-rows .st-acts { margin-top: 16px; }
  .st-grid .st-sites.is-rows .st-acts .primary { flex: 1; }
  /* The strip stays one line on a phone: three controls, right-aligned,
     wrapping only if the New course label needs it. */
  .st-grid .st-tools { gap: 6px; }
}

/* ══════════════════════════════════════════════════════════════════════
   "NEEDS SETUP" — the marker and the banner (L19)

   Alex, 2026-08-03: "a marker on each course tile to say that this one has got
   missing things in it and maybe a banner saying, 'You need to set these things
   up to make them work within' across the course page where all the tiles are"
   — and, in the same breath, "Not a banner that goes across the entire
   dashboard but a banner that sits within the course area."

   Both are ADVISORY. They use the warn tone, never the danger tone: nothing
   here blocks anything, and a red badge on a course that is live and selling
   would be a lie about its state.
   ══════════════════════════════════════════════════════════════════════ */
.st-grid .st-setup {
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 999px;
  background: rgba(24,20,10,.82); color: #fdf0d5;
  font-size: 10.5px; font-weight: 650; letter-spacing: .01em;
  backdrop-filter: blur(3px);
}
/* ⚠️ The [hidden] guard, for the FIFTH time today. An author display beats the
   UA rule, and without this every tile would carry the badge before the answer
   arrives — the exact false alarm the fired-not-awaited design avoids. */
.st-grid .st-setup[hidden] { display: none; }

.st-grid .st-setup-banner {
  margin: 0 0 14px; padding: 12px 15px; border-radius: 12px;
  background: var(--warn-soft, rgba(214,158,46,.12));
  border: 1px solid var(--warn-border, rgba(214,158,46,.32));
  color: var(--text); font-size: 13px; line-height: 1.5;
}
.st-grid .st-setup-banner[hidden] { display: none; }
.st-grid .st-setup-banner b { font-weight: 700; }
