:root {
  /* Neutrals — unchanged values, named. Do not introduce new greys. */
  --ink:            #111;   /* primary text, filled buttons */
  --ink-2:          #555;   /* secondary text, field values */
  --ink-3:          #888;   /* labels */
  --ink-4:          #aaa;   /* hints, placeholders, empty-state body */
  --line:           #e5e5e5;/* panel and section borders */
  --line-2:         #ddd;   /* input borders */
  --line-3:         #f0f0f0;/* row separators */
  --bg:             #f5f5f3;/* app background, sunken fills */
  --surface:        #fff;
  --hover:          #f0f0ee;/* editable-row hover */

  /* Geometry */
  --col:            640px;  /* the one content column width */
  --gutter:         132px;  /* read-view label gutter */
  --row-h:          32px;
  --row-pad:        7px 10px;
  --input-h:        34px;
  --r-input:        5px;    /* keep the app's existing 5px */
  --r-panel:        6px;
  --r-badge:        3px;
  --pad-panel:      20px;
  --gap-section:    24px;

  /* Production lifecycle badges — cool, low chroma, a progression */
  --life-upcoming-bg:        #eff1f5;  --life-upcoming-fg:        #4a5160;
  --life-auditions_open-bg:  #e4f0f8;  --life-auditions_open-fg:  #1f5b7a;
  --life-callback_stage-bg:  #e2f2ef;  --life-callback_stage-fg:  #17615a;
  --life-cast_confirmed-bg:  #e6f4ea;  --life-cast_confirmed-fg:  #1a7f37;
  --life-archived-bg:        #f5f5f5;  --life-archived-fg:        #6b6b6b;
  --life-archived-border:    #cfcfcf;

  /* Casting decision badges — higher chroma, decisive, not a progression */
  --cast-yes-bg:       #e6f4ea;  --cast-yes-fg:       #1a7f37;
  --cast-callback-bg:  #fbe4ef;  --cast-callback-fg:  #a3246b;
  --cast-maybe-bg:     #fff8e1;  --cast-maybe-fg:     #b45309;
  --cast-hold-bg:      #f0eeff;  --cast-hold-fg:      #5b4fcf;
  --cast-no-bg:        #fdecec;  --cast-no-fg:        #c02020;
  --cast-new-bg:       #f0f0f0;  --cast-new-fg:       #666;

  /* Notice banners — four tones, no more */
  --notice-info-bg:      #f1f4f8; --notice-info-rule:    #7d93b5; --notice-info-fg:    #34435c;
  --notice-caution-bg:   #fff8e6; --notice-caution-rule: #d99e0b; --notice-caution-fg: #664d03;
  --notice-closed-bg:    #f5f5f5; --notice-closed-rule:  #9a9a9a; --notice-closed-fg:  #555;
  --notice-error-bg:     #fdecec; --notice-error-rule:   #d05353; --notice-error-fg:   #8f1d1d;
}

/* ── Badges ─────────────────────────────────────────────────────────────
   Same geometry, different tone. Lifecycle (Shows.status) is cool and
   low-chroma because it's a sequence. Casting (Auditions.casting_status) is
   higher-chroma because it's a judgement. Staff tell the vocabularies apart
   by tone, never by shape. cast_confirmed/yes share green deliberately —
   the one permitted overlap; nothing else shares a tone across families.
   The dashed border means archived-or-restricted and nothing else. */
.badge {
  display: inline-flex; align-items: center;
  height: 20px; padding: 0 7px;
  border: 1px solid transparent;
  border-radius: var(--r-badge);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.05em; text-transform: uppercase;
  white-space: nowrap;
}
.badge[hidden] { display: none; }

.badge-life-upcoming       { background: var(--life-upcoming-bg);       color: var(--life-upcoming-fg); }
.badge-life-auditions_open { background: var(--life-auditions_open-bg); color: var(--life-auditions_open-fg); }
.badge-life-callback_stage { background: var(--life-callback_stage-bg); color: var(--life-callback_stage-fg); }
.badge-life-cast_confirmed { background: var(--life-cast_confirmed-bg); color: var(--life-cast_confirmed-fg); }
.badge-life-archived       { background: var(--life-archived-bg);       color: var(--life-archived-fg);
                             border: 1px dashed var(--life-archived-border); }

.badge-cast-yes      { background: var(--cast-yes-bg);      color: var(--cast-yes-fg); }
.badge-cast-callback { background: var(--cast-callback-bg); color: var(--cast-callback-fg); }
.badge-cast-maybe    { background: var(--cast-maybe-bg);    color: var(--cast-maybe-fg); }
.badge-cast-hold     { background: var(--cast-hold-bg);     color: var(--cast-hold-fg); }
.badge-cast-no       { background: var(--cast-no-bg);       color: var(--cast-no-fg); }
.badge-cast-new      { background: var(--cast-new-bg);      color: var(--cast-new-fg); }

/* ── Notice banners — four tones, no more ──────────────────────────────
   info: not-yet-open/scheduled, pool confirmation, waitlist-room notice.
   caution: archived/read-only. closed: registration closed, no-show (a
   normal state, not an error). error: not found, bad link. */
.notice {
  border: 1px solid var(--line);
  border-left: 3px solid var(--notice-info-rule);
  border-radius: 4px;
  padding: 10px 14px;
  font-size: 13px; line-height: 1.5;
}
.notice--info    { background: var(--notice-info-bg);    border-left-color: var(--notice-info-rule);    color: var(--notice-info-fg); }
.notice--caution { background: var(--notice-caution-bg); border-left-color: var(--notice-caution-rule); color: var(--notice-caution-fg); }
.notice--closed  { background: var(--notice-closed-bg);  border-left-color: var(--notice-closed-rule);  color: var(--notice-closed-fg); }
.notice--error   { background: var(--notice-error-bg);   border-left-color: var(--notice-error-rule);   color: var(--notice-error-fg); }

/* ── The one edit affordance ────────────────────────────────────────────
   Read state: label + value, no border, no icon. Hover: tint + inset ring,
   whole row is the hit target. Click swaps value for input/select, focused,
   select-all. Enter/blur saves. Esc reverts to data-original, no request.
   Empty values read as an em dash in --ink-4, never a placeholder-styled
   input. */
.editable-row {
  display: flex; align-items: center; gap: 12px;
  min-height: var(--row-h); padding: var(--row-pad);
  border-radius: 4px; cursor: text;
}
.editable-row:hover     { background: var(--hover); box-shadow: inset 0 0 0 1px var(--line); }
.editable-row--select   { cursor: pointer; }
.editable-row__label    { width: var(--gutter); flex: none; font-size: 12px; color: var(--ink-3); }
.editable-row__value    { font-size: 13px; font-weight: 500; color: var(--ink); }
.editable-row__value--empty { font-weight: 400; color: var(--ink-4); }
.editable-row__hint     { margin-left: auto; flex: none; font-size: 11px; color: var(--ink-3); }

.editable-row input,
.editable-row select {
  flex: 1; min-width: 0; height: 30px;
  padding: 0 8px; font-size: 13px; font-family: inherit;
  border: 1px solid var(--line-2); border-radius: 4px;
  background: var(--surface); color: var(--ink); outline: none;
}
.editable-row input:focus,
.editable-row select:focus { border-color: #4a6fa5; box-shadow: 0 0 0 3px #e3ecf7; }

/* ── Restricted / read-only controls ────────────────────────────────────
   Shipped unused — for the future RBAC view-only / archived-disabling
   pass. A restricted control gets the dashed treatment; a restricted panel
   gets one badge-readonly in its section header, not a tag on every row.
   No lock icon — the word "Read-only" and the dashed edge carry the
   meaning, and it survives greyscale/colour-blindness. */
.is-restricted,
.is-restricted:hover {
  background: var(--bg) !important;
  border: 1px dashed var(--line-2) !important;
  box-shadow: none !important;
  color: var(--ink-3) !important;
  cursor: not-allowed;
}
.is-restricted .badge-readonly,
.badge-readonly {
  margin-left: auto; flex: none;
  height: 18px; padding: 0 6px;
  border-radius: var(--r-badge);
  background: #ececec; color: var(--ink-2);
  font-size: 10px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
}

/* ── Empty states ────────────────────────────────────────────────────── */
.empty-state {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 28px 20px; text-align: center;
}
.empty-state__mark  { width: 30px; height: 30px; border: 1px dashed var(--line-2); border-radius: 4px; }
.empty-state__title { font-size: 13px; font-weight: 500; color: var(--ink); }
.empty-state__body  { max-width: 280px; font-size: 12px; line-height: 1.5; color: var(--ink-4); }

/* ── Helper text — a line of guidance under a field, not inline with the label */
.field-hint { font-size: 11px; font-weight: 400; color: var(--ink-4); margin-top: 4px; }

/* ── Inline rename trigger — for rows whose primary click is already taken
   (opening/previewing a file), so the whole row can't be the edit target.
   A word, not an icon, next to the existing small utility links. */
.rename-trigger { color: var(--ink-4); font-size: 11px; cursor: pointer; }
.rename-trigger:hover { color: var(--ink-2); }
.rename-input {
    flex: 1; min-width: 0; font-size: 12px; font-family: inherit;
    padding: 3px 6px; border: 1px solid var(--line-2); border-radius: 4px;
    outline: none; background: var(--surface); color: var(--ink);
}
.rename-input:focus { border-color: #4a6fa5; box-shadow: 0 0 0 3px #e3ecf7; }

/* ── Production header: title row + meta-pair row ──────────────────────
   Nothing in the meta row is bold — the title carries all the weight.
   A pair is omitted (not em-dashed) when its value is empty. */
.show-detail__titlerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.show-meta { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 8px;
             font-size: 13px; color: var(--ink-2); }
.meta-pair { display: inline-flex; gap: 7px; }
.meta-pair[hidden] { display: none; }
.meta-label { color: var(--ink-4); }
.meta-pair a { color: var(--ink-2); }
