/* ABOUTME: Shared "Editorial Native" design language — the single source of UI primitives. */

/* ABOUTME: Every member page renders these (.ps-page/.ph/.ps-card/.ps-list/.ps-row/...) for one cohesive look. */

/* ===== Page shell (the canvas every converted page sits on) ===== */
.ps-page {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;

  /* Glow retuned with the Sharpened Cream ground so it stays a subtle warm
     lift, not a pale patch on the deeper canvas. */
  background: radial-gradient(120% 70% at 85% 36%, #F8E4CB 0, rgb(248 228 203 / 0%) 52%), var(--cream);
  color: var(--ink);
  font-family: var(--font-ui, -apple-system, system-ui, sans-serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizelegibility;
  padding: 0 16px calc(28px + env(safe-area-inset-bottom, 0px));
}
.ps-page a { color: inherit; text-decoration: none; }

/* The link reset above out-specifies .ps-empty-cta (0,1,1 vs 0,1,0) — without this the
   empty-state CTA renders ink-on-orange instead of white. */
.ps-page a.ps-empty-cta { color: #fff; }

/* Form-button rows in grouped-inset lists (e.g. Connect Google = a real form POST).
   The form participates in the list via display:contents; the button resets to row chrome. */
.ps-row-form { display: contents; }
button.ps-row--button { width: 100%; background: none; border: 0; text-align: left; font: inherit; cursor: pointer; }
.ps-list .ps-row-form + .ps-row, .ps-list .ps-row + .ps-row-form > .ps-row { border-top: 1px solid var(--rule); }

/* No global top nav: main's padding-top clears only the status bar / notch,
   and .ps-page provides its side gutters. */

/* ===== Large-title header ===== */
.ph { display: flex; align-items: flex-start; gap: 12px; padding: 18px 2px 14px; }

.ph-back { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  background: var(--paper); border: 1px solid var(--rule); box-shadow: var(--specular), var(--e1); color: var(--ink); font-size: 16px; margin-top: 4px; }
.ph-id { flex: 1; min-width: 0; }
.ph-eyebrow { display: block; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-ink); margin-bottom: 3px; }
.ph-title { font-family: var(--font-display, Georgia, serif); font-weight: 600; font-size: 34px; letter-spacing: -.025em; line-height: 1.04; color: var(--ink); }
.ph-sub { display: block; margin-top: 4px; font-size: 13px; font-weight: 500; color: var(--ink-soft); }
.ph-actions { display: flex; align-items: center; gap: 10px; margin-top: 2px; }

.ph-action { width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  background: var(--paper); border: 1px solid var(--rule); box-shadow: var(--specular), var(--e1); color: var(--ink); font-size: 17px; position: relative; }
.ph-action.is-disabled { opacity: .35; pointer-events: none; }

/* Action-only toolbar for subnav'd pages: the pill row is the identity, so
   these pages drop the big title and keep just their header actions here. */
.ps-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 14px 2px 4px; }
.ps-toolbar:empty { display: none; }

/* Short intro lede — one line of context under a header or subnav band. On
   subnav'd pages (no big title, action-only toolbar) it also gives the top some
   breathing room so content doesn't butt against the fixed pill row. */
.ps-lede { margin: 4px 4px 16px; font-size: 14px; font-weight: 500; line-height: 1.5; color: var(--ink-soft); }

/* ===== Section label ===== */
.ps-section-label-row { display: flex; align-items: baseline; justify-content: space-between; margin: 22px 4px 10px; }
.ps-section-label { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.ps-section-trailing { font-size: 14px; font-weight: 700; color: var(--accent-ink); }

/* ===== Card primitive ===== */
.ps-card { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-tile); box-shadow: var(--specular), var(--e1); padding: 16px; }
.ps-card--feature { box-shadow: var(--specular), var(--e2); }

/* ===== Grouped-inset list ===== */
.ps-list { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-tile); box-shadow: var(--specular), var(--e1); overflow: hidden; }
.ps-row { display: flex; align-items: center; gap: 13px; padding: 14px 16px; min-height: 60px; color: var(--ink); }
.ps-row + .ps-row { border-top: 1px solid var(--rule); }
.ps-row-ic { width: 38px; height: 38px; border-radius: 12px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; font-size: 17px; background: var(--paper-2); color: var(--orange-600); }
.ps-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ps-row-title { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.ps-row-meta { font-size: 13px; color: var(--ink-soft); }
.ps-row-value { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); flex: 0 0 auto; }
.ps-row-badge { font-size: 12px; font-weight: 700; color: var(--accent-ink); background: var(--accent-wash); padding: 3px 9px; border-radius: 999px; flex: 0 0 auto; }
.ps-row-chev { color: var(--ink-faint); font-size: 15px; flex: 0 0 auto; }
a.ps-row:active { background: var(--paper-2); }

/* ===== Editable list row (Settings): trailing control saves on edit =====
   Text rows keep a real inline input. Select/date rows show a formatted
   value instead of the raw native control - the control becomes a full-row
   invisible overlay so tapping anywhere opens the native picker (iOS wheel /
   date sheet) while the row displays tidy, one-line text. */
.ps-row--field { flex-wrap: wrap; min-height: 52px; position: relative; }

/* flex-basis 0 (not auto): a text input's auto basis is its ~20ch intrinsic
   width regardless of value, which — under this row's flex-wrap — inflates the
   line and wraps the status slot to a second row on longer-titled fields (e.g.
   Nickname), padding the row's height and shifting the value's right edge. A 0
   basis lets the control grow into free space instead, so every field row keeps
   one line and its value aligns to the same right edge as select/date rows. */
.ps-row-control { flex: 1 1 0; display: flex; align-items: center; gap: 6px; min-width: 0; max-width: 64%; }

/* One wash per group, not one per row - see ps-row--field usages in profiles/show. */
.ps-row-ic--accent { background: var(--accent-wash); color: var(--accent-ink); }
.ps-row-ic--blue { background: var(--blue-wash); color: var(--steel); }
.ps-row--field .ps-row-ic { width: 28px; height: 28px; border-radius: 8px; font-size: 13px; }

.ps-row--field .ps-row-title { flex: 1 1 auto; min-width: 0; font-size: 15.5px; font-weight: 600; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.ps-row--field .ps-row-value { flex: 0 1 auto; max-width: 170px; font-size: 15px; font-weight: 500; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-row--field .ps-row-value.is-muted { color: var(--ink-faint); font-weight: 400; }

/* Text rows: the input IS the row's value display, so at rest it must be
   indistinguishable from .ps-row-value (same size/weight/ink, same right
   edge - the negative right margin cancels the input's own 4px text inset).
   While editing it darkens to full ink for legibility. */
.ps-row-input { font: inherit; font-size: 15px; font-weight: 500; color: var(--ink-soft); background: none; border: 0;
  text-align: right; padding: 6px 4px; margin: -6px -4px -6px 0; border-radius: 9px; min-width: 0; width: 100%;
  appearance: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-row-input::placeholder { color: var(--ink-faint); font-weight: 400; }
.ps-row-input:focus { color: var(--ink); }

.ps-row-input:focus-visible { outline: none; background: var(--paper-2); box-shadow: 0 0 0 2px var(--orange); }

/* The native select/date control: same footprint as the row, fully transparent.
   It still receives the tap/click and opens the OS picker; the formatted
   ps-row-value span is what's actually visible. */
.ps-row-overlay { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0;
  background: none; opacity: 0; appearance: none; cursor: pointer; }

/* opacity: 0 hides the control but it still receives focus, so the keyboard
   ring has to paint on the row - :has() reaches up from the overlay's own
   :focus-visible state to its row ancestor. .ps-list clips to its own
   rounded corners, so the first/last row's ring needs the same radius or
   it gets clipped square against the curve. */
.ps-row--field:has(.ps-row-overlay:focus-visible) { outline: none; background: var(--paper-2); box-shadow: inset 0 0 0 2px var(--orange); }
.ps-row--field:first-child:has(.ps-row-overlay:focus-visible) { border-radius: var(--radius-tile) var(--radius-tile) 0 0; }
.ps-row--field:last-child:has(.ps-row-overlay:focus-visible) { border-radius: 0 0 var(--radius-tile) var(--radius-tile); }
.ps-row--field:only-child:has(.ps-row-overlay:focus-visible) { border-radius: var(--radius-tile); }

/* Fixed-width status slot so saving/saved/error never shifts the row. */
.ps-field-status { flex: 0 0 auto; width: 16px; text-align: center; font-size: 13px; opacity: 0; transition: opacity .2s var(--ease-out); }
.ps-field-status[data-state="saving"] { opacity: .6; color: var(--ink-faint); }
.ps-field-status[data-state="saved"] { opacity: 1; color: var(--success-600); }
.ps-field-status[data-state="error"] { opacity: 1; color: var(--error-600); }
.ps-field-error { display: none; flex-basis: 100%; margin: 4px 0 0 41px; font-size: 13px; color: var(--error-600); }
.ps-row--field.has-error .ps-field-error { display: block; }

.ps-row--field.has-error .ps-row-input,
.ps-row--field.has-error .ps-row-value { color: var(--error-600); }

/* Checkbox rows: a right-aligned native check, sized as a comfortable touch target. */
.ps-row-checkbox { flex: 0 0 auto; width: 22px; height: 22px; accent-color: var(--orange); cursor: pointer; }
.ps-row-checkbox:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--orange); border-radius: 6px; }

/* Textarea + multi-select rows: the control is too tall for one line, so it
   breaks to its own full-width line beneath the label. */
.ps-row--field-textarea, .ps-row--field-multiselect { align-items: flex-start; }

.ps-row-textarea, .ps-row-multiselect { flex: 0 0 100%; width: 100%; margin-top: 10px; font: inherit; font-size: 15px;
  color: var(--ink); background: var(--paper-2); border: 1px solid var(--rule); border-radius: 10px; padding: 9px 11px;
  appearance: none; }
.ps-row-textarea { min-height: 84px; resize: vertical; line-height: 1.45; }
.ps-row-multiselect { min-height: 132px; }
.ps-row-textarea:focus-visible, .ps-row-multiselect:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--orange); }

/* Exercise instructional-video block: responsive 16:9 player, or a
   non-clickable error when the URL is not a recognized video. */
.ex-video { margin-top: 12px; }
.ex-video-heading { margin: 0 0 8px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-faint); }
.ex-video-frame { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: 10px; background: var(--paper-2); }
.ex-video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.ex-video-error { display: flex; align-items: center; gap: 8px; margin: 0; padding: 11px 13px; border-radius: 10px;
  background: var(--error-50, #FEF2F2); color: var(--error-600, #DC2626); font-size: 13px; font-weight: 500; }

/* Long free-text rows (alternate names, video URL) break onto their own
   full-width line so the value/placeholder isn't squeezed and truncated. */
.ps-row--field-full { align-items: flex-start; }
.ps-row--field-full .ps-row-control { flex: 0 0 100%; max-width: 100%; margin-top: 10px; }

.ps-row--field-full .ps-row-input { text-align: left; margin: 0; padding: 9px 11px; background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: 10px; color: var(--ink); }
.ps-row--field-full .ps-row-input:focus-visible { box-shadow: 0 0 0 2px var(--orange); }

/* ===== Empty state ===== */
.ps-empty { text-align: center; padding: 26px 18px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.ps-empty-ic { width: 52px; height: 52px; border-radius: 16px; display: flex; align-items: center; justify-content: center; font-size: 24px; background: var(--paper-2); }
.ps-empty-title { font-size: 16px; font-weight: 700; color: var(--ink); }
.ps-empty-body { font-size: 14px; color: var(--ink-soft); max-width: 30ch; }

.ps-empty-cta { display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 18px; border-radius: 14px; background: var(--orange); color: #fff; font-weight: 700; font-size: 15px;
  box-shadow: 0 3px 10px rgb(232 116 59/30%), 0 14px 28px -14px rgb(232 116 59/70%); }

/* ===== Segmented control (e.g. Train: Schedule | Library) ===== */
.ps-segmented { display: flex; gap: 4px; padding: 4px; background: var(--paper-2); border: 1px solid var(--rule); border-radius: 15px; }
.ps-seg { flex: 1; text-align: center; min-height: 40px; display: flex; align-items: center; justify-content: center; gap: 7px; font-size: 15px; font-weight: 600; color: var(--ink-soft); border-radius: 11px; }
.ps-seg.is-active { background: var(--paper); color: var(--ink); box-shadow: var(--specular), var(--e1); }

.ps-seg-count { font-size: 11.5px; font-weight: 800; min-width: 20px; height: 20px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-wash); color: var(--accent-ink); border-radius: 999px; }

.ps-seg.is-active .ps-seg-count { background: var(--accent-ink); color: #fff; }

/* ===== Desktop: the editorial column breathes, the large title scales up =====
   Phone-first metrics above are untouched; this only relaxes the canvas where
   there's room. The global top nav remains the chrome on every viewport. */
@media (width >= 769px) {
  .ps-page { max-width: 640px; padding-left: 24px; padding-right: 24px; }
  .ph { padding-top: 30px; }
  .ph-title { font-size: 40px; }
}
.ph-title { text-wrap: balance; }

/* ===== Pointer affordances — :active covers touch; hover is for desktop ===== */
a.ps-row, .ph-back, .ph-action, .ps-empty-cta { transition: background .15s var(--ease-out), box-shadow .15s var(--ease-out); }
a.ps-card { display: block; transition: box-shadow .15s var(--ease-out); }

@media (hover: hover) {
  a.ps-row:hover { background: var(--paper-2); }
  .ph-back:hover, a.ph-action:hover, button.ph-action:hover { background: var(--paper-2); }
  a.ps-card:hover { box-shadow: var(--specular), var(--e2); }
  .ps-card--feature[href]:hover { box-shadow: var(--specular), var(--e3); }
  .ps-empty-cta:hover { box-shadow: 0 3px 10px rgb(232 116 59/40%), 0 18px 34px -14px rgb(232 116 59/80%); }
}

/* ===== Focus ring (AA) ===== */
.ps-page a:focus-visible, .ph-action:focus-visible, .ps-empty-cta:focus-visible, .ps-seg:focus-visible {
  outline: 3px solid var(--orange); outline-offset: 2px; border-radius: 12px;
}

/* ===== Progress page specifics (heatmap rebuilt AA-safe: 7×2 grid, ≥44px cells, non-color signal + legend) ===== */
.ps-heatmap { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }

.ps-hm-cell { aspect-ratio: 1; min-height: 44px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: var(--paper); border: 1px solid var(--rule); color: var(--ink-soft); position: relative; }
.ps-hm-day { font-size: 11px; font-weight: 700; color: var(--ink-faint); }
.ps-hm-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--rule); }
.ps-hm-cell.is-today { box-shadow: 0 0 0 2px var(--orange); }

/* grade fills — warm, paired with the day label + legend (never color-only) */
.ps-hm--excellent { background: var(--sage-wash); } .ps-hm--excellent .ps-hm-dot { background: var(--sage); }
.ps-hm--good      { background: #EEF3EA; }          .ps-hm--good .ps-hm-dot      { background: #82A079; }
.ps-hm--solid     { background: #FBF1E0; }          .ps-hm--solid .ps-hm-dot     { background: var(--yellow); }
.ps-hm--focus     { background: var(--accent-wash); } .ps-hm--focus .ps-hm-dot   { background: var(--orange); }
.ps-hm-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 12px; font-size: 12px; color: var(--ink-soft); }
.ps-hm-legend span { display: inline-flex; align-items: center; gap: 6px; }
.ps-hm-legend i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

/* Count pill (e.g. the unresolved-reports badge on the chatrooms list). */
.ps-pill { font-size: 13px; font-weight: 600; color: var(--accent-ink); background: var(--accent-wash); padding: 5px 11px; border-radius: 999px; font-variant-numeric: tabular-nums; }
