/*
 * CS DISPLAY — COMPONENTS
 *
 * Reads tokens and nothing else. No hard-coded colour, size, spacing, radius
 * or font anywhere below — if a value appears here that a skin cannot change,
 * that is a bug in the token contract, not something to patch locally.
 *
 * Mobile first throughout. Every component is designed at 375px and allowed
 * to grow, never designed at 1440 and squeezed.
 *
 * ONE ACCEPTED EXCEPTION: the breakpoint values in @media rules are literals.
 * CSS media queries cannot read custom properties — it is a language
 * limitation, not an oversight. --cs-bp-* exists so skin authors and the
 * drawer JS read the same numbers; the queries below restate them. Changing a
 * breakpoint means editing both, and there is no way around that without a
 * build step, which this plugin deliberately does not have.
 */

/* ==== FOUNDATION ======================================================== */

.cs { color: var(--cs-ink); background: var(--cs-paper); font-family: var(--cs-font-sans); }
.cs *, .cs *::before, .cs *::after { box-sizing: border-box; }

.cs :focus-visible {
  outline: var(--cs-focus-width) solid var(--cs-focus-color);
  outline-offset: var(--cs-focus-offset);
}

.cs-container { max-width: var(--cs-container); margin-inline: auto; padding-inline: var(--cs-space-4); }

/* THE THEME TIE — read before styling any heading or link below.
 *
 * WordPress 6.6+ prints the active theme's element styles as
 * `:root :where(h2)` and `:root :where(a:where(:not(.wp-element-button)))`:
 * specificity (0,1,0), exactly one class, and printed AFTER this sheet. A
 * tie goes to whoever printed last, so a heading rule written as `.cs-x`
 * lost its font, size and colour to the theme on the first real boot.
 *
 * The rule here: any class that lands on a heading or an anchor carries an
 * element qualifier — `:is(h1,h2,h3,h4,h5,h6).cs-x`, `a.cs-x` — which is
 * (0,1,1) and wins, and states colour and line-height outright so the
 * theme has nothing left to fill in. tools/wp-lab/bleed.py audits this
 * against a real block theme; it is the gate for this comment. */

.cs-label,
:is(h1, h2, h3, h4, h5, h6).cs-label,
.cs-stats dt,
.cs-badge,
.cs-verified,
.cs-featured,
.cs-empty__eyebrow,
.cs-drawer__legend,
.cs-safety h3,
.cs-profile__credentials h2,
.cs-card__avail,
.cs-incomplete {
  font-size: var(--cs-label-size);
  font-weight: var(--cs-label-weight);
  letter-spacing: var(--cs-label-tracking);
  text-transform: var(--cs-label-transform);
  font-family: var(--cs-font-sans);
}
.cs-label, :is(h1, h2, h3, h4, h5, h6).cs-label { color: var(--cs-ink-3); line-height: var(--cs-leading-snug); }

/* The screen-reader-only idiom. The 1px values are the standard hack, not
 * design values — there is nothing here for a skin to change. */
.cs-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* The skip link a block template gets from core and a plugin-served page does
 * not: hidden until a keyboard reaches it, then the first thing on the page. */
.cs-skip:not(:focus) { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.cs-skip:focus { position: fixed; z-index: 100000; inset-block-start: var(--cs-space-2); inset-inline-start: var(--cs-space-2); padding: var(--cs-space-3) var(--cs-space-4); background: var(--cs-paper); color: var(--cs-ink); outline: var(--cs-focus-width) solid var(--cs-focus-color); }

/* ==== 1 · CARD ==========================================================
 * The anti-dating-app constraint lives here, and it is enforced by the
 * browser rather than trusted to content volume.
 *
 * Three attempts, each measured in a browser, because each read as correct
 * in the stylesheet:
 *   1. container queries — an element cannot query ITSELF, so 100cqw
 *      resolved against the viewport: 3,906px cards, image at 9%.
 *   2. aspect-ratio (share / image-h) — the cap held, but the card was 2.5×
 *      as tall as wide and ordinary data left a void under every card.
 *   3. grid rows, below — exact by construction, no void.
 * tools/wp-lab/walk.mjs measures the share on the rendered directory, so a
 * fourth attempt cannot pass on the stylesheet alone.
 */
.cs-card {
  /* DECISION: two grid rows, image then data, in the skin's proportion
   * (--cs-card-rows, derived from --cs-card-image-share). The cap is now
   * exact by construction rather than approximated by an aspect-ratio:
   *
   * The aspect-ratio version made the card 2.5× as tall as it was wide and
   * let space-between push the footer down, so every card with ordinary data
   * carried a void under its chips — a hundred empty pixels on a phone, in
   * every card, on the page the whole product is judged by. Here the DATA
   * decides the card's height, the image takes the same share of it, and
   * object-fit crops the photograph to whatever shape that is. The image
   * never exceeds its share, and nothing is empty.
   *
   * A floor keeps a sparse card from shrinking the photograph to a strip:
   * the media's ::before holds it at least 4:5-landscape tall, which only
   * leaves air in the data half of a card with almost nothing to say. */
  display: grid;
  grid-template-rows: var(--cs-card-rows);
  background: var(--cs-paper);
  border: var(--cs-border-width) solid var(--cs-rule);
  border-radius: var(--cs-radius);
  /* NO overflow:hidden on the card: a grid item's automatic minimum size
   * becomes 0 with it, and long content would be clipped rather than grow
   * the card. The media block clips itself. */
}

.cs-card__media {
  min-height: 0;
  background: var(--cs-paper-3);
  position: relative;
  overflow: hidden;
}
/* DECISION: !important, once, on purpose. Images::frame() prints an inline
 * aspect-ratio (4:5 by default, right for a lone image), and inline beats
 * any selector. Inside a card the ROW owns the image's shape — a caller that
 * forgot 'ratio' => 'auto' put a 4:5 floor under the photograph and a void
 * under every card's data. The skins gate caught it; this makes it
 * impossible rather than a convention every caller must know. */
.cs-card > .cs-card__media { aspect-ratio: auto !important; }
.cs-card__media::before { content: ""; display: block; aspect-ratio: var(--cs-card-image-floor); }

.cs-card__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  /* No gradient overlay, ever. An overlay on a face is the single most
   * dating-app gesture available and it buys nothing here. */
}

.cs-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-3);
  padding: var(--cs-space-5) var(--cs-space-4) var(--cs-space-4);
  min-width: 0;
}

/* Group the identity block so space-between distributes ONE gap at the
 * bottom rather than scattering gaps between every line. The first render
 * clumped all the data at the top and left a void above the verification
 * line — restrained is not the same as empty, and it read as broken. */
.cs-card__ident { display: flex; flex-direction: column; gap: var(--cs-space-2); }

.cs-card__name, :is(h1, h2, h3, h4, h5, h6).cs-card__name {
  font-family: var(--cs-font-display);
  font-size: var(--cs-text-lg);
  line-height: var(--cs-leading-tight);
  letter-spacing: var(--cs-tracking-tight);
  font-weight: var(--cs-weight-medium);
  color: inherit;
  margin: 0;
}

.cs-card__name a { color: inherit; text-decoration: none; }
.cs-card__name a:hover { text-decoration: underline; text-underline-offset: 0.15em; }

.cs-card__roles { font-size: var(--cs-text-sm); color: var(--cs-ink-2); line-height: var(--cs-leading-snug); margin: 0; }
/* A recent credit is what a printed casting directory actually carries, and
 * it is the line that makes the card about WORK rather than appearance. It
 * also fills the data half honestly — the first two passes left a void under
 * the stats, and the fix was missing content, not a smaller image. */
.cs-card__credit {
  font-size: var(--cs-text-sm);
  line-height: var(--cs-leading-snug);
  color: var(--cs-ink-2);
  margin: 0;
  padding-top: var(--cs-space-2);
  border-top: var(--cs-border-width) solid var(--cs-rule);
}
.cs-card__credit .cs-label { display: block; margin-bottom: var(--cs-space-1); }

.cs-card__foot {
  margin-top: auto;
  padding-top: var(--cs-space-3);
  border-top: var(--cs-border-width) solid var(--cs-rule);
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--cs-space-1) var(--cs-space-2);
}
.cs-card__avail {
  font-size: var(--cs-label-size); font-weight: var(--cs-label-weight);
  letter-spacing: var(--cs-label-tracking); text-transform: var(--cs-label-transform);
  color: var(--cs-ink-3); margin-left: auto;
}

.cs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--cs-card-min-width), 1fr));
  gap: var(--cs-card-gap);
}

/* ==== 2 · STAT ROW ======================================================
 * Physical stats are tabular and visually subordinate. Never a hero.
 */
.cs-stats { display: grid; grid-template-columns: auto 1fr; gap: var(--cs-space-2) var(--cs-space-3); margin: 0; font-size: var(--cs-text-sm); }
.cs-stats dt { color: var(--cs-ink-3); align-self: baseline; }
.cs-stats dd { margin: 0; color: var(--cs-ink); font-variant-numeric: tabular-nums; }
.cs-stats--compact { font-size: var(--cs-text-xs); }

/* ==== 3 · CHIP ========================================================== */
.cs-chips { display: flex; flex-wrap: wrap; gap: var(--cs-space-1); list-style: none; margin: 0; padding: 0; }
.cs-chip, a.cs-chip {
  display: inline-block;
  padding: var(--cs-space-1) var(--cs-space-2);
  font-size: var(--cs-text-xs);
  line-height: var(--cs-leading-tight);
  color: var(--cs-ink-2);
  background: var(--cs-paper-2);
  border: var(--cs-border-width) solid var(--cs-rule);
  border-radius: var(--cs-radius);
  text-decoration: none;
}
.cs-chip:hover, a.cs-chip:hover { color: var(--cs-ink); border-color: var(--cs-ink-3); text-decoration: none; }
.cs-chip[aria-pressed="true"], a.cs-chip[aria-pressed="true"] { background: var(--cs-accent); color: var(--cs-accent-ink); border-color: var(--cs-accent); }

/* ==== 4 · BADGE ========================================================= */
.cs-badge {
  display: inline-flex; align-items: center; gap: var(--cs-space-1);
  font-size: var(--cs-label-size); font-weight: var(--cs-label-weight);
  letter-spacing: var(--cs-label-tracking); text-transform: var(--cs-label-transform);
  padding: var(--cs-space-1) var(--cs-space-2);
  border: var(--cs-border-width) solid currentColor;
  border-radius: var(--cs-radius);
  color: var(--cs-ink-2);
}
.cs-badge--rate { color: var(--cs-ink); }
.cs-badge--tfp { color: var(--cs-ink-2); }

/* ==== 5 · VERIFICATION BADGE ===========================================
 * Deliberately typographic. A blue tick is a social-platform signal and
 * reads as status; this is a factual statement about identity checks.
 */
.cs-verified { display: inline-flex; align-items: center; gap: var(--cs-space-1);  color: var(--cs-positive); }
.cs-verified::before { content: ""; width: 0.5em; height: 0.5em; background: currentColor; flex: 0 0 auto; }
.cs-verified--none { color: var(--cs-ink-3); }
.cs-verified--none::before { background: transparent; border: var(--cs-hairline) solid currentColor; }

/*
 * FEATURED — a paid placement, and it says so.
 *
 * The member pays for this and cannot otherwise tell it worked: a rank
 * change is indistinguishable from the nightly rotation seed. It is also a
 * disclosure — a visitor reading a directory is entitled to know that a
 * position was bought. Typographic for the same reason as .cs-verified:
 * a badge that looks like a platform endorsement would be claiming something
 * about the member rather than about the listing.
 */
.cs-featured { color: var(--cs-ink-2); }
.cs-featured::before { content: ""; display: inline-block; width: 0.45em; height: 0.45em; margin-inline-end: var(--cs-space-1); background: currentColor; transform: rotate(45deg); }

/* ==== 6 · AVATAR ======================================================== */
.cs-avatar { aspect-ratio: var(--cs-avatar-ratio); width: var(--cs-space-16); background: var(--cs-paper-3); border-radius: var(--cs-radius); overflow: hidden; flex: 0 0 auto; }
.cs-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ==== 7 · GALLERY GRID ==================================================
 * Uniform, gridded, captioned. A portfolio index, not a feed: no masonry,
 * no infinite scroll, no varying tile sizes competing for attention.
 */
.cs-gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--cs-space-2); list-style: none; margin: 0; padding: 0; }
@media (min-width: 46rem) { .cs-gallery { grid-template-columns: repeat(3, 1fr); gap: var(--cs-space-3); } }
@media (min-width: 64rem) { .cs-gallery { grid-template-columns: repeat(4, 1fr); } }
.cs-gallery__item { margin: 0; }
.cs-gallery__frame { aspect-ratio: var(--cs-gallery-ratio); background: var(--cs-paper-3); overflow: hidden; border-radius: var(--cs-radius); }
.cs-gallery__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-gallery__caption { font-size: var(--cs-text-xs); color: var(--cs-ink-3); margin-top: var(--cs-space-1); line-height: var(--cs-leading-snug); }
.cs-gallery__figure { margin: 0; }

/* Owner's editing surface. cs-media renders the controls; the look is ours.
 * Visitors never see these — the markup is only emitted for the owner. */
.cs-gallery__item.is-primary .cs-gallery__frame { outline: 2px solid var(--cs-accent); outline-offset: 2px; }
.cs-gallery__item.is-dragging { opacity: 0.5; }
.cs-gallery__tools { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); align-items: center; justify-content: space-between; margin-top: var(--cs-space-2); }
.cs-gallery__order, .cs-gallery__acts { display: flex; gap: var(--cs-space-1); align-items: center; }
.cs-gallery__tools button {
  font: inherit; font-size: var(--cs-text-xs); line-height: 1;
  min-height: var(--cs-target-min); padding: 0 0.6em;
  border: var(--cs-border-width) solid var(--cs-rule); border-radius: var(--cs-radius);
  background: var(--cs-paper); color: var(--cs-ink-2); cursor: pointer;
}
.cs-gallery__tools button:hover { color: var(--cs-ink); border-color: var(--cs-ink-3); }
.cs-gallery__tools button[aria-pressed="true"] { background: var(--cs-accent); color: var(--cs-accent-ink); border-color: var(--cs-accent); }
.cs-gallery__tools .cs-gallery__delete { color: var(--cs-critical); border-color: transparent; background: transparent; }
.cs-gallery__tools .cs-gallery__delete:hover { border-color: var(--cs-critical); color: var(--cs-critical); }
.cs-gallery__alt-label { display: block; margin-bottom: var(--cs-space-1); font-size: var(--cs-label-size); font-weight: var(--cs-label-weight); letter-spacing: var(--cs-label-tracking); text-transform: var(--cs-label-transform); color: var(--cs-ink-3); }
.cs-gallery__status[data-cs-missing="0"] .cs-gallery__status-todo,
.cs-gallery__status:not([data-cs-missing="0"]) .cs-gallery__status-done { display: none; }
.cs-gallery__handle { cursor: grab; touch-action: none; }
/* WCAG 2.2 · 2.5.8 Target Size (Minimum) is 24x24 CSS px; these are the
 * non-drag reorder alternative required by 2.5.7. */
.cs-gallery__move, .cs-gallery__handle { min-width: var(--cs-target-min); min-height: var(--cs-target-min); justify-content: center; }
.cs-gallery__alt { flex: 1 1 100%; }
/* box-sizing stated here: the gallery editor also renders inside shortcodes
 * on pages that have no .cs root, where the reset above does not reach, and
 * 100% + padding + border was 6px of sideways scroll on a classic theme. */
.cs-gallery__alt input { box-sizing: border-box; width: 100%; font: inherit; font-size: var(--cs-text-xs); padding: 0.35em 0.5em; border: var(--cs-border-width) solid var(--cs-rule); border-radius: var(--cs-radius); background: var(--cs-paper); color: var(--cs-ink); }
.cs-gallery__status { font-size: var(--cs-text-xs); color: var(--cs-ink-3); margin-top: var(--cs-space-2); }

/* ==== 8 · JOB ROW =======================================================
 * Jobs are scanned, not browsed. A list row, not a card.
 */
.cs-jobs { list-style: none; margin: 0; padding: 0; border-top: var(--cs-border-width) solid var(--cs-rule); }
.cs-job {
  display: grid; gap: var(--cs-space-1);
  padding: var(--cs-space-4) 0;
  border-bottom: var(--cs-border-width) solid var(--cs-rule);
}
@media (min-width: 46rem) {
  .cs-job { grid-template-columns: 1fr auto; align-items: baseline; column-gap: var(--cs-space-6); }
  .cs-job__meta { grid-column: 1; }
  .cs-job__aside { grid-column: 2; grid-row: 1 / span 2; text-align: right; }
}
.cs-job__title, :is(h1, h2, h3, h4, h5, h6).cs-job__title { font-size: var(--cs-text-md); font-weight: var(--cs-weight-medium); line-height: var(--cs-leading-snug); font-family: var(--cs-font-sans); color: inherit; margin: 0; }
.cs-job__title a { color: inherit; text-decoration: none; }
.cs-job__title a:hover { text-decoration: underline; text-underline-offset: 0.15em; }
.cs-job__meta { font-size: var(--cs-text-sm); color: var(--cs-ink-2); display: flex; flex-wrap: wrap; gap: var(--cs-space-1) var(--cs-space-3); }
.cs-job__aside { font-size: var(--cs-text-xs); color: var(--cs-ink-3); }
.cs-job--expired { opacity: 0.55; }

/* ==== 9 · EMPTY STATE ===================================================
 * NOT A FOOTNOTE. With zero profiles and zero jobs this is the product —
 * the screen most visitors will see, with more impressions than any profile
 * on the site. It is laid out as a real screen and given real hierarchy.
 */
.cs-empty { padding: var(--cs-space-16) var(--cs-space-4); max-width: var(--cs-measure); margin-inline: auto; text-align: left; }
.cs-empty__eyebrow { color: var(--cs-ink-3); }
.cs-empty__title, :is(h1, h2, h3, h4, h5, h6).cs-empty__title { font-family: var(--cs-font-display); font-size: var(--cs-text-2xl); line-height: var(--cs-leading-tight); letter-spacing: var(--cs-tracking-tight); margin: var(--cs-space-3) 0 var(--cs-space-4); font-weight: var(--cs-weight-normal); color: inherit; }
.cs-empty__body { font-size: var(--cs-text-md); line-height: var(--cs-leading-normal); color: var(--cs-ink-2); margin: 0 0 var(--cs-space-6); }
.cs-empty__actions { display: flex; flex-wrap: wrap; gap: var(--cs-space-3); }
.cs-empty__loosen { margin-top: var(--cs-space-8); padding-top: var(--cs-space-6); border-top: var(--cs-border-width) solid var(--cs-rule); }
.cs-empty__loosen ul { list-style: none; margin: var(--cs-space-3) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }

/* ==== 10 · SKELETON ===================================================== */
.cs-skeleton { background: var(--cs-paper-3); position: relative; overflow: hidden; }
.cs-skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--cs-paper-2), transparent);
  transform: translateX(-100%);
  animation: cs-sheen 1.4s infinite;
}
@keyframes cs-sheen { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .cs-skeleton::after { animation: none; } }

/* ==== 11 · FILTER DRAWER ================================================
 * A real drawer on mobile, not a collapsed accordion pretending to be one.
 * Keyboard navigable and focus-trapped; the facets are the entire point of
 * the taxonomy URL strategy and they cannot be pointer-only.
 */
.cs-drawer-toggle { display: inline-flex; align-items: center; gap: var(--cs-space-2); }
.cs-drawer {
  position: fixed; inset: 0 0 0 auto; width: min(var(--cs-drawer-width), 88vw);
  background: var(--cs-paper); border-left: var(--cs-border-width) solid var(--cs-rule);
  padding: var(--cs-space-6) var(--cs-space-4);
  overflow-y: auto; z-index: 60;
  transform: translateX(100%);
  transition: transform var(--cs-duration) var(--cs-easing);
}
.cs-drawer[data-open="true"] { transform: translateX(0); visibility: visible; }
/* A translated-offscreen drawer is still tabbable and still read by screen
 * readers. visibility:hidden removes it from both until it opens. */
.cs-drawer:not([data-open="true"]) { visibility: hidden; transition: transform var(--cs-duration) var(--cs-easing), visibility 0s linear var(--cs-duration); }
.cs-drawer__scrim { position: fixed; inset: 0; background: rgb(0 0 0 / 0.35); z-index: 55; }
.cs-drawer__group + .cs-drawer__group { margin-top: var(--cs-space-6); padding-top: var(--cs-space-4); border-top: var(--cs-border-width) solid var(--cs-rule); }
.cs-drawer__legend { color: var(--cs-ink-3); margin-bottom: var(--cs-space-2); }
/* DECISION: sidebar or drawer is decided by the room the DIRECTORY has, not
 * by the viewport. A classic theme's content column is ~45rem at any screen
 * size, and the viewport query put a 15rem sidebar beside ONE column of
 * 400px cards there — the photograph as tall as the phone layout's, on a
 * desktop. A container query gives that column the drawer and two columns
 * of cards, and gives a full-width block theme the sidebar and three.
 * 50rem is the sidebar plus two card columns at their minimum width.
 * (drawer.js reads the result from the computed style, so the two agree.) */
.cs-directory-page { container: cs-directory / inline-size; }
@container cs-directory (min-width: 50rem) {
  .cs-drawer, .cs-drawer:not([data-open="true"]) { position: static; width: auto; transform: none; visibility: visible; border-left: 0; padding: 0; overflow: visible; }
  /* Two classes, not one: .cs-btn sets display too and comes later in this
   * sheet, so `.cs-drawer-toggle { display:none }` lost and the Filter button
   * sat above a sidebar that was already open. */
  .cs-drawer__scrim, .cs-directory .cs-drawer-toggle, .cs-directory--filterable .cs-directory__bar, .cs-drawer .cs-drawer__head { display: none; }
}

/* The drawer's own header — title and a visible way out. Sticky, so the
 * close control stays under the thumb however far the facets scroll. */
.cs-drawer__head {
  position: sticky; top: calc(-1 * var(--cs-space-6)); z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: var(--cs-space-3);
  margin: calc(-1 * var(--cs-space-6)) calc(-1 * var(--cs-space-4)) var(--cs-space-5);
  padding: var(--cs-space-4);
  background: var(--cs-paper);
  border-bottom: var(--cs-border-width) solid var(--cs-rule);
}
:is(h1, h2, h3, h4, h5, h6).cs-drawer__title { margin: 0; font-family: var(--cs-font-display); font-size: var(--cs-text-lg); font-weight: var(--cs-weight-normal); line-height: var(--cs-leading-tight); color: var(--cs-ink); }
.cs-drawer__close {
  display: grid; place-items: center; flex: 0 0 auto;
  width: var(--cs-target-touch); height: var(--cs-target-touch);
  font: inherit; font-size: 1.5rem; line-height: 1; color: var(--cs-ink);
  background: transparent; border: var(--cs-border-width) solid var(--cs-rule); border-radius: var(--cs-radius);
  cursor: pointer;
}
.cs-drawer__close:hover { border-color: var(--cs-ink); }

/* In the drawer the chips are the controls, so they are sized for a thumb. */
@container cs-directory (max-width: 49.99rem) {
  .cs-drawer a.cs-chip { display: inline-flex; align-items: center; min-height: 40px; padding-inline: var(--cs-space-3); font-size: var(--cs-text-sm); }
}

/* A chip's count reads as a count: quieter than its label, and aligned. */
.cs-chip__count { margin-inline-start: 0.45em; color: var(--cs-ink-3); font-variant-numeric: tabular-nums; }
a.cs-chip[aria-pressed="true"] .cs-chip__count { color: inherit; }
.cs-drawer-toggle__n {
  display: inline-grid; place-items: center; min-width: 1.4em; height: 1.4em; padding: 0 0.3em;
  font-size: var(--cs-text-xs); font-variant-numeric: tabular-nums;
  color: var(--cs-accent-ink); background: var(--cs-accent); border-radius: var(--cs-radius-pill);
}

/* The directory page: toolbar, results, and — when the directory has the
 * room — the drawer as a sidebar beside the grid. Without it the drawer is
 * fixed and the grid has the whole width. */
.cs-directory__bar { display: flex; align-items: center; gap: var(--cs-space-4); margin-bottom: var(--cs-space-5); }
.cs-directory__count { margin: 0; }
.cs-directory__results { min-width: 0; }
@container cs-directory (min-width: 50rem) {
  .cs-directory--filterable { display: grid; grid-template-columns: var(--cs-sidebar-width) minmax(0, 1fr); gap: var(--cs-space-8); align-items: start; }
  .cs-directory--filterable .cs-directory__bar { grid-column: 1 / -1; }
  .cs-directory--filterable .cs-drawer { position: sticky; top: var(--cs-space-4); }
}
.cs-drawer__active .cs-chip[aria-pressed="true"] { text-decoration: none; }

/* ==== PAGE HEAD =========================================================
 * The heading a visitor reads first: where they are. The directory carried
 * its title only as screen-reader text, so someone arriving from search on
 * /models/commercial/culver-city/ saw a filter button and a grid and nothing
 * saying what either was of. */
.cs-page-head { margin: var(--cs-space-8) 0 var(--cs-space-6); }
.cs-page-head--split { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--cs-space-4); }
:is(h1, h2, h3, h4, h5, h6).cs-page-head__title {
  margin: 0;
  font-family: var(--cs-font-display); font-size: var(--cs-text-2xl); font-weight: var(--cs-weight-normal);
  line-height: var(--cs-leading-tight); letter-spacing: var(--cs-tracking-tight); color: var(--cs-ink);
}
@media (min-width: 46rem) { :is(h1, h2, h3, h4, h5, h6).cs-page-head__title { font-size: var(--cs-text-3xl); } }
.cs-page-head__meta { margin: var(--cs-space-2) 0 0; font-size: var(--cs-text-sm); color: var(--cs-ink-2); font-variant-numeric: tabular-nums; }

.cs-backlink { margin: var(--cs-space-6) 0 var(--cs-space-3); font-size: var(--cs-text-sm); }
.cs-backlink a, a.cs-backlink { color: var(--cs-ink-2); text-decoration: none; }
.cs-backlink a:hover { color: var(--cs-ink); text-decoration: underline; text-underline-offset: 0.15em; }

/* Long-form text from an editor: a listing's description, a bio. */
.cs-prose { max-width: var(--cs-measure); font-size: var(--cs-text-md); line-height: var(--cs-leading-normal); color: var(--cs-ink); }
.cs-prose > * + * { margin-top: var(--cs-space-4); }
.cs-prose a { color: inherit; text-underline-offset: 0.15em; }

.cs-job-single { max-width: calc(var(--cs-measure) + var(--cs-space-16)); padding-bottom: var(--cs-space-12); }
:is(h1, h2, h3, h4, h5, h6).cs-job-single__title {
  margin: 0 0 var(--cs-space-5);
  font-family: var(--cs-font-display); font-size: var(--cs-text-2xl); font-weight: var(--cs-weight-normal);
  line-height: var(--cs-leading-tight); letter-spacing: var(--cs-tracking-tight); color: var(--cs-ink);
}
@media (min-width: 46rem) { :is(h1, h2, h3, h4, h5, h6).cs-job-single__title { font-size: var(--cs-text-3xl); } }
.cs-job-single__facts { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0 var(--cs-space-6); margin: 0 0 var(--cs-space-8); }
.cs-job-single__facts > div { display: grid; gap: var(--cs-space-1); padding: var(--cs-space-2) 0; border-bottom: var(--cs-border-width) solid var(--cs-rule); }
.cs-job-single__facts dt { font-size: var(--cs-label-size); letter-spacing: var(--cs-label-tracking); text-transform: var(--cs-label-transform); font-weight: var(--cs-label-weight); }
.cs-job-single .cs-btn { margin-top: var(--cs-space-8); }

/* The profile's own way to the form, at the top of a long page. */
.cs-profile__actions { margin: var(--cs-space-5) 0 0; display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }
.cs-profile__contact { scroll-margin-top: var(--cs-space-8); margin-top: var(--cs-space-12); padding-top: var(--cs-space-6); border-top: var(--cs-border-width) solid var(--cs-rule); max-width: var(--cs-measure); }
/* The section carries the rule now, with its heading under it; the block
 * cs-contact prints keeps its own rule everywhere else it is used. */
.cs-profile__contact > .cs-contact { margin-top: 0; padding-top: 0; border-top: 0; }
:is(h1, h2, h3, h4, h5, h6).cs-profile__section-title { margin: 0 0 var(--cs-space-3); }

/* ==== 12 · PAGINATION =================================================== */
.cs-pagination { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); align-items: center; margin-top: var(--cs-space-12); padding-top: var(--cs-space-6); border-top: var(--cs-border-width) solid var(--cs-rule); }
.cs-pagination a, .cs-pagination span { padding: var(--cs-space-2) var(--cs-space-3); font-size: var(--cs-text-sm); text-decoration: none; color: var(--cs-ink-2); border: var(--cs-border-width) solid var(--cs-rule); border-radius: var(--cs-radius); }
.cs-pagination [aria-current="page"] { background: var(--cs-accent); color: var(--cs-accent-ink); border-color: var(--cs-accent); }

/* ==== 13 · SAFETY NOTICE ================================================
 * Present, legible, and not styled as a warning banner people learn to skip.
 * It is a standing condition of using the site, so it reads as body text
 * with a rule, not as an alert.
 */
.cs-safety { border-left: var(--cs-border-width-heavy) solid var(--cs-ink); padding: var(--cs-space-3) 0 var(--cs-space-3) var(--cs-space-4); margin: var(--cs-space-6) 0; font-size: var(--cs-text-sm); line-height: var(--cs-leading-normal); color: var(--cs-ink-2); }
.cs-safety h3 { color: var(--cs-ink); margin: 0 0 var(--cs-space-2); }
.cs-safety ul { margin: 0; padding-left: var(--cs-space-4); }
.cs-safety li + li { margin-top: var(--cs-space-1); }

/* ==== BUTTON ============================================================ */
.cs-btn, a.cs-btn {
  display: inline-block; padding: var(--cs-space-3) var(--cs-space-6);
  font-family: var(--cs-font-sans); font-size: var(--cs-text-sm); font-weight: var(--cs-weight-medium); line-height: var(--cs-leading-snug);
  background: var(--cs-accent); color: var(--cs-accent-ink);
  border: var(--cs-border-width) solid var(--cs-accent); border-radius: var(--cs-radius);
  text-decoration: none; cursor: pointer;
  transition: opacity var(--cs-duration) var(--cs-easing);
}
.cs-btn:hover, a.cs-btn:hover { opacity: 0.85; color: var(--cs-accent-ink); text-decoration: none; }
.cs-btn--ghost, a.cs-btn--ghost { background: transparent; color: var(--cs-ink); border-color: var(--cs-rule); }
.cs-btn--ghost:hover, a.cs-btn--ghost:hover { border-color: var(--cs-ink); opacity: 1; }

/* ==== GATE — cs-unseal's sign-in and upgrade prompts ====================
 * Emitted by cs_require_login() / cs_upgrade_prompt(). Styled here so a
 * theme that calls them gets a card in the skin, not two bare links. */
.cs-gate { border: var(--cs-border-width) solid var(--cs-rule); border-radius: var(--cs-radius); background: var(--cs-paper-2); padding: var(--cs-space-5); margin: var(--cs-space-5) 0; }
.cs-gate p { margin: 0 0 var(--cs-space-3); }
.cs-gate p:last-child { margin: 0; display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }

/* ==== PROFILE HEADER ====================================================
 * Credentials and work history ABOVE THE FOLD, beside the photo. Physical
 * stats subordinate and below. The order of these blocks is the difference
 * between a professional directory and a dating profile.
 */
/* Section rhythm. Everything under the head is a slot another plugin fills
 * — gallery, contact, report — so the space between sections is owned here
 * by the container, not by whichever sibling happens to be active. On the
 * first real boot the gallery sat flush against the portrait, and two beige
 * placeholders read as one. Blocks with their own top margin (.cs-contact,
 * .cs-report) come later in this sheet and keep it. */
.cs-profile > * + * { margin-top: var(--cs-space-8); }
.cs-profile__head { display: grid; gap: var(--cs-space-6); }
@media (min-width: 46rem) { .cs-profile__head { grid-template-columns: minmax(0, var(--cs-portrait-column)) minmax(0, 1fr); align-items: start; } }
.cs-profile__portrait { aspect-ratio: var(--cs-card-image-ratio); background: var(--cs-paper-3); overflow: hidden; border-radius: var(--cs-radius); }
.cs-profile__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-profile__name, :is(h1, h2, h3, h4, h5, h6).cs-profile__name { font-family: var(--cs-font-display); font-size: var(--cs-text-3xl); line-height: var(--cs-leading-tight); letter-spacing: var(--cs-tracking-tight); margin: 0 0 var(--cs-space-2); font-weight: var(--cs-weight-normal); color: inherit; }
.cs-profile__credentials { margin: var(--cs-space-4) 0 0; }
.cs-profile__credentials h2 { color: var(--cs-ink-3); margin: 0 0 var(--cs-space-2); line-height: var(--cs-leading-snug); }
.cs-profile__physical { margin-top: var(--cs-space-8); padding-top: var(--cs-space-4); border-top: var(--cs-border-width) solid var(--cs-rule); }

/* ==== INCOMPLETE PROFILE ================================================
 * Profiles with two photos will outnumber good ones early. They must read as
 * "in progress", never as broken — an apologetic card makes the whole
 * directory look abandoned.
 */
.cs-card--sparse .cs-card__media { background: var(--cs-paper-2); }
.cs-card--sparse .cs-card__body { color: var(--cs-ink-2); }
.cs-incomplete { color: var(--cs-ink-3); }

/* ======================================================================
   THE PROFILE PAGE'S SLOTS — identity, statistics, contact, report
   ----------------------------------------------------------------------
   Four class families land on the profile page from siblings (cs-core's
   identity and stats, cs-contact's form and report) and for the life of
   the framework none of them had a rule here. The contact form rendered
   as raw browser controls. These are the rules; the register is the
   same as everything above — hairlines, labels, no chrome.
   ====================================================================== */

/* identity: roles · location · verified */
.cs-profile__identity {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--cs-space-2) var(--cs-space-3);
	margin: 0 0 var(--cs-space-4);
	font-size: var(--cs-text-md);
	color: var(--cs-ink-2);
}
.cs-profile__identity .cs-roles { display: inline-flex; flex-wrap: wrap; gap: 0 var(--cs-space-2); color: var(--cs-ink); }
.cs-profile__identity .cs-sep { color: var(--cs-rule); }
.cs-profile__identity .cs-verified { align-self: center; }

/* statistics on the page: a tabular strip, not a form. Four across on a
   wide screen so the eye reads left to right once; two on a phone. */
.cs-stats--profile {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 var(--cs-space-6);
	font-size: var(--cs-text-sm);
}
@media (min-width: 46rem) { .cs-stats--profile { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.cs-stats--profile > div {
	display: grid;
	gap: var(--cs-space-1);
	padding: var(--cs-space-2) 0;
	border-bottom: var(--cs-border-width) solid var(--cs-rule);
}
.cs-stats--profile dt { font-size: var(--cs-label-size); letter-spacing: var(--cs-label-tracking); text-transform: var(--cs-label-transform); font-weight: var(--cs-label-weight); }

/* contact and report: the form the whole product converts on */
.cs-contact { margin-top: var(--cs-space-12); padding-top: var(--cs-space-6); border-top: var(--cs-border-width) solid var(--cs-rule); max-width: var(--cs-measure); }
.cs-contact .cs-safety, .cs-contact .cs-remaining, .cs-report__note { font-size: var(--cs-text-sm); color: var(--cs-ink-2); line-height: var(--cs-leading-normal); }
.cs-contact .cs-safety { margin: 0 0 var(--cs-space-5); padding: var(--cs-space-3) var(--cs-space-4); background: var(--cs-paper-2); }
.cs-contact .cs-remaining { margin: var(--cs-space-3) 0 0; }
.cs-contact label, .cs-report label, .cs-age label {
	display: block;
	font-size: var(--cs-label-size);
	letter-spacing: var(--cs-label-tracking);
	text-transform: var(--cs-label-transform);
	font-weight: var(--cs-label-weight);
	color: var(--cs-ink-3);
	margin: var(--cs-space-4) 0 var(--cs-space-1);
}
.cs-contact input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
.cs-contact select, .cs-contact textarea,
.cs-report input:not([type="hidden"]), .cs-report select, .cs-report textarea,
.cs-age input[type="date"] {
	width: 100%;
	box-sizing: border-box;
	font: inherit;
	font-size: var(--cs-text-md);
	color: var(--cs-ink);
	background: var(--cs-paper);
	border: var(--cs-border-width) solid var(--cs-rule);
	border-radius: var(--cs-radius);
	padding: var(--cs-space-2) var(--cs-space-3);
	min-height: var(--cs-target-min);
}
.cs-contact input:focus, .cs-contact select:focus, .cs-contact textarea:focus,
.cs-report input:focus, .cs-report select:focus, .cs-report textarea:focus {
	outline: var(--cs-focus-width) solid var(--cs-focus-color);
	outline-offset: var(--cs-focus-offset);
	border-color: var(--cs-ink);
}
.cs-contact button[type="submit"], .cs-contact .cs-btn, .cs-report button[type="submit"] {
	display: inline-flex;
	align-items: center;
	min-height: var(--cs-target-touch);
	margin-top: var(--cs-space-5);
	padding: 0 var(--cs-space-6);
	font: inherit;
	font-size: var(--cs-text-md);
	color: var(--cs-accent-ink);
	background: var(--cs-accent);
	border: var(--cs-border-width) solid var(--cs-accent);
	border-radius: var(--cs-radius);
	cursor: pointer;
	text-decoration: none;
}
/* The measure, like the contact block above it: a 1,150px select on a
 * desktop profile read as a form field for the whole page. */
.cs-report { margin-top: var(--cs-space-8); font-size: var(--cs-text-sm); max-width: var(--cs-measure); }
.cs-report a { color: inherit; }
.cs-report summary { cursor: pointer; color: var(--cs-ink-3); }
.cs-report__done { color: var(--cs-positive); }
.cs-report summary:hover { color: var(--cs-ink); }
.cs-age { margin: var(--cs-space-4) 0 0; }
.cs-age input[type="checkbox"] { width: var(--cs-target-min); height: var(--cs-target-min); vertical-align: middle; margin: 0 var(--cs-space-2) 0 0; }
