/* Client portal (Your Jewellery Box) — the UC parti design system.
 * Tokens from docs/design-system/tokens/ (colors.css is authoritative):
 * cream #faf7f2 · ink #1a1a1a · teal #013A52 · gold #c9a96e, parti gradient
 * thin-only (2-4px, max ONE per view, always 105deg). Marcellus display
 * (18 Jul decision — one weight, no italic; emphasis via size and
 * letterspacing) · Jost body · IBM Plex Mono ledger (facts only). Radius 0,
 * no shadows — depth is hairlines, 1px ink rules and surface shifts.
 *
 * STANDALONE stylesheet, linked only by layouts/portal.html.erb — it MUST be
 * stubbed out of the public Sprockets bundle (see the `stub portal` line in
 * application.css): its bare element selectors are un-layered CSS and would
 * override Tailwind's @layer utilities on every public page. */

.portal {
  --uc-cream: #faf7f2;
  --uc-cream-deep: #f3eee5;
  --uc-ink: #1a1a1a;
  --uc-ink-soft: #4a4a45;
  --uc-ink-faint: #8a8578;
  --uc-teal: #013A52;
  --uc-teal-wash: #0a4a66;
  --uc-gold: #c9a96e;
  --uc-gold-deep: #b0905a;
  --uc-line: #e2dccf;
  /* The signature. Always 105deg. Thin and directional only — never a wash. */
  --uc-parti: linear-gradient(105deg,
    #013A52 0%, #0A5468 40%, #2F7263 62%, #97904A 82%, #C9A96E 100%);
  --display: 'Marcellus', Georgia, serif;
  --sans: 'Jost', 'Helvetica Neue', sans-serif;
  --mono: 'IBM Plex Mono', 'Courier New', monospace;

  margin: 0;
  min-height: 100vh;
  background: var(--uc-cream);
  color: var(--uc-ink);
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

.portal * {
  box-sizing: border-box;
}

/* ---- header: the wordmark, plus the design exit when it is switched on ----
 * Pure white on the cream page: the value shift is the separator, no rule.
 * The storefront exit and its maker's mark were removed 24 September 2026;
 * .portal-exit and .portal-exit-caption below now serve the design exit only,
 * and the maker's mark signs the page once, in the footer. */

.portal-header {
  width: 100%;
  background: #ffffff;
}

.portal-header-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 24px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
}

/* The wordmark face is Baskerville Old Face ONLY — never headings or body.
 * Centred, at the UC site's logotype scale. */
.portal a.portal-wordmark {
  grid-column: 2;
  grid-row: 1;
  font-family: 'Baskerville Old Face', 'Baskerville', Georgia, serif;
  font-size: 44px;
  letter-spacing: 0.02em;
  color: var(--uc-ink);
  text-decoration: none;
  white-space: nowrap;
  text-align: center;
}

/* On desktop the nav dissolves into the header grid so the design exit sits in
 * column 3 beside the centred wordmark; at phone width it reassembles as a
 * small row below. The nav renders only when that exit does. */
.portal-exits {
  display: contents;
}

/* The header grid is 1fr auto 1fr and the wordmark names column 2, so it stays
   centred whether or not this renders. Since 24 September 2026 column 1 is
   always empty: nothing sits opposite this any more. */
.portal a.portal-exit--design {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
}

.portal-exit-design {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--uc-ink);
}

.portal a.portal-exit {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--uc-ink);
  text-decoration: none;
}

.portal-exit-caption {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
  transition: color 150ms ease;
}

.portal a.portal-exit:hover .portal-exit-caption {
  color: var(--uc-teal);
}

/* Content column; the footer below it is full-bleed. */
.portal-main {
  flex: 1 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px 16px 64px;
}

.portal h1,
.portal h2 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.15;
  color: var(--uc-ink);
  margin: 0;
}

.portal a {
  color: var(--uc-teal);
  text-decoration: underline;
  text-decoration-color: var(--uc-gold);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 150ms ease;
}

.portal a:hover {
  color: var(--uc-teal-wash);
  text-decoration-thickness: 2px;
}

/* ---- flash ---- */

.portal-flash {
  width: 100%;
  max-width: 26rem;
  margin: 0 auto 16px;
  padding: 12px 16px;
  font-size: 15px;
  border: 1px solid var(--uc-line);
  background: var(--uc-cream-deep);
  color: var(--uc-ink);
}

.portal-flash--alert {
  border-color: var(--uc-ink);
}

/* ---- the auth / content card ---- */

.portal-card {
  width: 100%;
  max-width: 26rem;
  margin: 8vh auto 0;
  background: var(--uc-cream);
  border: 1px solid var(--uc-line);
  /* The view's ONE parti element: a 3px top edge (a strip, not a wash). */
  background-image: var(--uc-parti);
  background-size: 100% 3px;
  background-repeat: no-repeat;
  background-position: top;
  padding: 39px 28px 32px;
}

.portal-card h1 {
  font-size: 26px;
  margin: 0 0 6px;
}

.portal-card .portal-lede {
  color: var(--uc-ink-soft);
  font-size: 15px;
  margin: 0 0 24px;
}

.portal-card label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: var(--uc-ink);
  margin: 18px 0 6px;
}

.portal-card input[type='email'],
.portal-card input[type='password'] {
  width: 100%;
  padding: 11px 14px;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 400;
  color: var(--uc-ink);
  background: var(--uc-cream);
  border: 1px solid var(--uc-ink);
  border-radius: 0;
  outline: none;
}

.portal-card input:focus {
  outline: 1px solid var(--uc-teal);
  outline-offset: 1px;
}

.portal-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  font-size: 14px;
  color: var(--uc-ink-soft);
}

.portal-check label {
  all: unset;
  font-size: 14px;
  color: var(--uc-ink-soft);
}

.portal-card .portal-submit {
  display: block;
  width: 100%;
  margin-top: 26px;
  padding: 12px 24px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--uc-cream);
  background: var(--uc-teal);
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: background 150ms ease;
}

.portal-card .portal-submit:hover {
  background: var(--uc-teal-wash);
}

.portal-links {
  margin-top: 20px;
  font-size: 14px;
  text-align: center;
}

.portal-errors {
  margin: 0 0 16px;
  padding: 11px 14px;
  border: 1px solid var(--uc-ink);
  background: var(--uc-cream-deep);
  font-size: 14px;
  color: var(--uc-ink);
}

.portal-errors ul {
  margin: 3px 0 0 18px;
  padding: 0;
}

/* ---- signed-in shell ---- */

.portal-shell {
  width: 100%;
  max-width: 34rem;
  margin: 6vh auto 0;
  text-align: center;
}

.portal-mark {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
  margin-bottom: 32px;
}

.portal-shell h1 {
  font-size: 34px;
  margin: 0 0 12px;
}

.portal-shell .portal-rule {
  width: 56px;
  height: 1px;
  background: var(--uc-line);
  border: none;
  margin: 22px auto;
}

.portal-shell p {
  color: var(--uc-ink-soft);
  margin: 0 auto;
  max-width: 28rem;
}

.portal-signout {
  margin-top: 40px;
}

.portal-signout button {
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0.04em;
  color: var(--uc-teal);
  background: none;
  border: none;
  border-bottom: 1px solid var(--uc-gold);
  cursor: pointer;
  padding: 0 0 2px;
  transition: color 150ms ease;
}

.portal-signout button:hover {
  color: var(--uc-teal-wash);
  border-bottom-width: 2px;
}

/* ---- dashboard ---- */

/* Content column. .portal-main centres this on the cross axis, so each page
   sizes its wrap to what it holds — otherwise a narrow reading column pools
   against the left of an over-wide wrap and reads as off-centre on desktop. */
.portal-wrap {
  width: 100%;
  max-width: 1120px;
  margin: 24px auto 0;
  padding: 0 8px;
}

/* Dashboard: the job-card grid. Sized to hold three cards across, centred. */
.portal-wrap--dash {
  max-width: 52rem;
}

/* Job and thread pages: a single reading column (ledger/stages/messages are
   all a 36rem measure) — centre it rather than stranding it left. */
.portal-wrap--reading {
  max-width: 37rem;
}

.portal-wrap h1 {
  font-size: 34px;
}

/* The view's ONE parti element: the heading underline. */
.portal-parti-rule {
  width: 72px;
  height: 3px;
  background: var(--uc-parti);
  margin: 18px 0 24px;
}

.portal-greeting {
  color: var(--uc-ink-soft);
  margin: 0 0 6px;
}

.portal-dash-lede {
  color: var(--uc-ink-faint);
  margin: 0 0 40px;
}

.portal-section-heading {
  font-size: 20px;
  margin: 0 0 16px;
}

.portal-jobcards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}

.portal-jobcard {
  background: var(--uc-cream);
  border: 1px solid var(--uc-line);
  transition: border-color 150ms ease;
}

.portal-jobcard:hover {
  border-color: var(--uc-ink);
}

.portal a.portal-jobcard-link {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  color: var(--uc-ink);
  text-decoration: none;
}

.portal-jobcard-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: 20px;
  line-height: 1.3;
  color: var(--uc-ink);
}

.portal-jobcard-stage {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
}

.portal-empty {
  color: var(--uc-ink-soft);
  max-width: 34rem;
}

/* ---- job page: the ruled ledger (facts, mono) + the stage story ---- */

.portal-ledger {
  max-width: 36rem;
  background: var(--uc-cream);
  border: 1px solid var(--uc-ink);
  padding: 20px 24px;
  font-family: var(--mono);
}

.portal-ledger-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  border-bottom: 1px solid var(--uc-ink);
  padding-bottom: 10px;
  margin-bottom: 4px;
}

.portal-ledger-title {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--uc-ink);
}

.portal-ledger-issuer {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--uc-ink-faint);
  text-align: right;
}

.portal-ledger-table {
  width: 100%;
  border-collapse: collapse;
}

.portal-ledger-table tr {
  border-bottom: 1px solid var(--uc-line);
}

.portal-ledger-table tr:last-child {
  border-bottom: none;
}

.portal-ledger-label {
  padding: 9px 16px 9px 0;
  vertical-align: top;
  white-space: nowrap;
  width: 1%;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
}

.portal-ledger-value {
  padding: 9px 0;
  text-align: right;
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--uc-ink);
  overflow-wrap: anywhere;
}

/* The reserved-stone qualifier, sitting under its stone's title. Shaped from
   the estimate qualifier below so the two read as one family; existing tokens
   only, no new colour. Block, so it never runs on as part of the title. */
.portal-ledger-qualifier {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--uc-ink-soft);
}

/* Estimated completion — a ledger-consistent row (label left, month right)
   with the estimate-only qualifier welded beneath. Inside the ledger card,
   separated from the table by a hairline. */
.portal-estimate {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--uc-line);
}

.portal-estimate-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
}

.portal-estimate-label {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
}

.portal-estimate-value {
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--uc-ink);
  text-align: right;
}

.portal-estimate-qualifier {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--uc-ink-soft);
}

.portal-stages {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  max-width: 36rem;
}

.portal-stage {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--uc-line);
}

.portal-stage:last-child {
  border-bottom: none;
}

.portal-stage-label {
  font-family: var(--display);
  font-weight: 400;
  font-size: 20px;
  color: var(--uc-ink);
}

.portal-stage--current .portal-stage-label {
  color: var(--uc-teal);
}

.portal-stage-date {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--uc-ink-soft);
  white-space: nowrap;
}

.portal-stage-now {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-teal);
  border: 1px solid var(--uc-teal);
  padding: 2px 8px;
  white-space: nowrap;
}

.portal-back {
  margin-top: 48px;
  font-size: 14px;
}

/* ---- conversations ---- */

.portal-threads {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 36rem;
}

.portal-thread-card {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--uc-line);
}

.portal-thread-card:last-child {
  border-bottom: none;
}

.portal-thread-date {
  font-family: var(--mono);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--uc-ink-soft);
  white-space: nowrap;
}

/* "New message". The same species of mark as .portal-stage-now, which is
 * the only bordered pill the portal has: mono, 11px, 0.14em, uppercase,
 * teal on a 1px teal rule, radius 0 like everything else here. It says
 * that something is waiting and nothing more, so it needs no colour of
 * its own and must not read louder than the piece name beside it.
 *
 * margin-right: auto on the thread card pushes the date back to the right
 * edge, where it already sits on every card without a marker. */
.portal-new-message {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-teal);
  border: 1px solid var(--uc-teal);
  padding: 2px 8px;
  white-space: nowrap;
}

.portal-thread-card .portal-new-message {
  margin-right: auto;
}

.portal-jobcard-link .portal-new-message {
  align-self: flex-start;
}

.portal-messages {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  max-width: 36rem;
}

.portal-message {
  background: var(--uc-cream-deep);
  border: 1px solid var(--uc-line);
  padding: 14px 16px;
  margin: 0 0 12px;
}

.portal-message--own {
  background: var(--uc-cream);
}

.portal-message-author {
  font-weight: 500;
  margin-right: 12px;
}

.portal-message-date {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
}

.portal-message-body p {
  margin: 8px 0 0;
}

.portal-compose {
  max-width: 36rem;
}

.portal-compose textarea {
  width: 100%;
  padding: 11px 14px;
  font-family: var(--sans);
  font-size: 15px;
  color: var(--uc-ink);
  background: var(--uc-cream);
  border: 1px solid var(--uc-ink);
  border-radius: 0;
  outline: none;
  resize: vertical;
}

.portal-compose textarea:focus {
  outline: 1px solid var(--uc-teal);
  outline-offset: 1px;
}

.portal-compose .portal-submit {
  display: inline-block;
  margin-top: 12px;
  padding: 12px 24px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--uc-cream);
  background: var(--uc-teal);
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: background 150ms ease;
}

.portal-compose .portal-submit:hover {
  background: var(--uc-teal-wash);
}

/* Preview mode: read-only render as another participant, clearly bannered,
 * with the way back inside the banner. */
.portal-banner--preview {
  width: 100%;
  margin: 0 0 24px;
  padding: 10px 14px;
  background: var(--uc-cream-deep);
  border: 1px solid var(--uc-ink);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink);
}

.portal a.portal-banner-return {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-teal);
  white-space: nowrap;
}

.portal-preview-links {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 14px;
}

/* The space under a section heading, and it has to be set HERE.
 *
 * .portal-section-heading declares `margin: 0 0 16px`, and that bottom margin
 * has never applied on the portal: `.portal h1, .portal h2 { margin: 0 }`
 * above is a class plus a type (0,1,1) and beats a bare class (0,1,0), so it
 * wins. The margin-top below is only applied because THIS selector is two
 * classes (0,2,0) and outranks it; the bottom was simply never restated.
 *
 * Measured in a browser before the fix: "The making of it" sat 16px above its
 * list, because .portal-stages carries its own margin-top, while "Messages",
 * "Ask us something" and the dashboard's "Your commissions" sat at 0px hard
 * against the box below them. The stages heading is unchanged by this, since
 * 16px against its list's 16px collapses to 16px.
 */
.portal-wrap .portal-section-heading {
  margin-top: 40px;
  margin-bottom: 16px;
}

/* ---- footer: teal inverse panel, full-bleed ---- */

.portal-footer {
  flex-shrink: 0;
  width: 100%;
  background: var(--uc-teal);
  color: var(--uc-cream);
}

.portal-footer-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 20px 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The three-punch maker's mark, recoloured to currentColor via CSS mask.
 * A brand device, never presented as an official assay mark. Size and the
 * gap-equals-size/4 rule ride inline from the shared punches partial
 * (footer 28px — doubled at the 18 Jul review; header exits 16px). */
.portal-punches {
  display: inline-flex;
  align-items: center;
  opacity: 0.85;
}

.portal-punch {
  display: inline-block;
  background: currentColor;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* ---- job page: the estimates staff have shared (increment 5) ----
   The job page is one full-width .portal-wrap holding the reading column in
   two halves, each exactly as wide as .portal-wrap--reading made it (37rem
   less the wrap's 8px padding either side), with the estimates' wide band
   between them, so estimates and their options can sit side by side.
   Everything wraps and nothing is wider than its container, so no width
   scrolls sideways. Existing tokens only. */

.portal-reading {
  max-width: calc(37rem - 16px);
  margin-left: auto;
  margin-right: auto;
}

.portal-shared {
  margin-top: 32px;
  margin-bottom: 32px;
}

.portal-shared-about,
.portal-shared-note {
  max-width: 37rem;
  color: var(--uc-ink-soft);
}

.portal-shared-about {
  margin: 0 0 16px;
}

.portal-shared-note {
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.5;
}

.portal-shared-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 20px;
}

.portal-shared-card {
  flex: 0 1 auto;
  max-width: 100%;
  box-sizing: border-box;
  background: var(--uc-cream);
  border: 1px solid var(--uc-ink);
  padding: 20px 24px;
}

.portal-shared-card--expired {
  border-color: var(--uc-line);
}

.portal-shared-heading {
  margin: 0;
  font-size: 18px;
}

.portal-shared-reference,
.portal-shared-validity {
  margin: 4px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--uc-ink-faint);
}

.portal-shared-card--expired .portal-shared-validity {
  color: var(--uc-ink-soft);
}

.portal-shared-options {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 24px;
  margin-top: 16px;
}

/* A fixed width capped by max-width. Not min(100%, ...) and not a flex basis:
   the card sizes to its options, and with either of those the options wrap at
   any width (measured, spec/system/portal_shared_estimates_spec.rb). On a
   phone, where they stack anyway, each fills the card. */
.portal-shared-option {
  width: 15rem;
  max-width: 100%;
}

@media (max-width: 480px) {
  .portal-shared-card {
    flex-basis: 100%;
  }

  .portal-shared-option {
    width: 100%;
  }
}

.portal-shared-option-heading {
  margin: 0 0 8px;
  font-size: 15px;
}

.portal-shared-figures {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 13px;
}

.portal-shared-figures tr {
  border-bottom: 1px solid var(--uc-line);
}

.portal-shared-figures th {
  padding: 6px 12px 6px 0;
  text-align: left;
  font-weight: 400;
  color: var(--uc-ink-soft);
}

.portal-shared-figures td {
  padding: 6px 0;
  text-align: right;
  white-space: nowrap;
  color: var(--uc-ink);
}

.portal-shared-total th,
.portal-shared-total td {
  border-top: 1px solid var(--uc-ink);
  font-weight: 600;
  color: var(--uc-ink);
}

.portal-shared-outside th,
.portal-shared-outside td,
.portal-shared-card--expired .portal-shared-figures td {
  color: var(--uc-ink-faint);
}

/* ---- 360px phones: single column, no horizontal scroll ---- */

@media (max-width: 720px) {
  .portal-header-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 24px 16px 16px;
  }

  .portal a.portal-wordmark {
    font-size: 32px;
  }

  .portal-exits {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
    flex-wrap: wrap;
  }
}

@media (max-width: 400px) {
  .portal-main {
    padding: 16px 12px 48px;
  }

  .portal-card {
    margin-top: 4vh;
    padding: 27px 18px 24px;
  }

  .portal-shell h1,
  .portal-wrap h1 {
    font-size: 26px;
  }
}

/* ————— Care & services + Bookings (Increment F3) —————
   Tiles reuse .portal-jobcards / .portal-jobcard; the tile itself is a BUTTON
   (the grid was link-only until now) reset to the anchor treatment. Radius 0,
   hairlines only, no new parti — the view's one rule is spent on the h1.
   Single column on phones falls out of the jobcards grid. */

.portal-care,
.portal-bookings {
  margin-top: 48px;
}

.portal-care-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--uc-ink-soft);
  margin: 0 0 8px;
}

.portal-care-note {
  color: var(--uc-ink-soft);
  max-width: 34rem;
  margin: 0 0 8px;
}

.portal-care-group {
  margin-top: 24px;
}

.portal-care-group-label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
  margin: 0 0 12px;
}

.portal-care-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 24px;
  margin: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  font: inherit;
  color: var(--uc-ink);
  text-align: left;
  cursor: pointer;
}

.portal-care-sub {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uc-ink-faint);
}

.portal-care-fallback-link {
  display: block;
  padding: 0 24px 20px;
  color: var(--uc-ink);
}

.portal-care-embed {
  margin-top: 16px;
  border: 1px solid var(--uc-line);
  background: var(--uc-cream);
}

/* A DEFINITE height, not min-height. Calendly's initInlineWidget appends a bare
   <iframe> (plus its spinner) straight into this element — there is no
   .calendly-inline-widget wrapper on this code path — and that iframe carries no
   height of its own. A percentage height on the iframe resolves against this
   element's `height`, never against `min-height`: under min-height alone the
   computed height stays `auto`, the iframe falls back to the 150px intrinsic
   default for a replaced element, and the whole calendar scrolls inside a
   sliver. Keep `height` here and `height: 100%` below together — either alone
   reintroduces the collapse.

   This value is the starting height; once the widget reports its own content
   height the Stimulus controller sizes this element to it. It is also the
   height that stands if that report never arrives, so it is set to comfortably
   clear the date picker on a phone. */
.portal-care-embed-frame {
  height: 900px;
}

.portal-care-embed-frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.portal-care-fallback {
  margin: 0;
  padding: 16px 20px;
}

.portal-care-fallback a {
  color: var(--uc-ink);
}

.portal-booking-list {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  border-top: 1px solid var(--uc-ink);
}

.portal-booking-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 0;
  border-bottom: 1px solid var(--uc-line);
}

.portal-booking-line {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}

.portal-booking-status {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--uc-ink-faint);
}

.portal-booking-row--cancelled .portal-booking-line {
  color: var(--uc-ink-faint);
  text-decoration: line-through;
}
