/* Portal chrome typography.
   Set from the database via App.razor, so a change on the branding screen reaches
   every page without a rebuild. The fallbacks keep the portal readable if branding
   cannot be read at all. */
body,
.rz-body,
input, select, textarea, button {
  font-family: var(--portal-body-font, system-ui, -apple-system, 'Segoe UI', sans-serif);
}

h1, h2, h3, h4, h5, h6,
.op-auth__title,
.op-auth__company,
.op-adminbrand__name {
  font-family: var(--portal-heading-font, system-ui, -apple-system, 'Segoe UI', sans-serif);
}

/* Offer page styling. Every colour and metric comes from the per-offering theme
   emitted as CSS custom properties, so branding is data rather than code. */

.op-root {
  background: var(--op-bg);
  color: var(--op-text);
  font-family: var(--op-body-font);
}

.op-root h1, .op-root h2, .op-root h3 {
  font-family: var(--op-heading-font);
  letter-spacing: -0.02em;
}

.op-block { display: block; }

.op-section {
  max-width: var(--op-max-width);
  margin: 0 auto;
  padding: 4rem 1.5rem;
}

.op-section__heading {
  font-size: calc(2rem * var(--op-heading-scale));
  margin-bottom: 1.5rem;
}

.op-muted { color: var(--op-muted); }

/* hero */
.op-hero {
  position: relative;

  /* Reduced 30% from 460/60vh. The earlier size still pushed whatever followed - a
     paired video, most often - too far down the page. Tall enough to carry the
     headline and the progress bar, short enough that a visitor can see there is more
     without scrolling to find out. */
  min-height: 322px;
  max-height: 42vh;
  display: flex;

  /* stretch, not center: the inner box needs the hero's full height so it can place
     the button within it. The inner box centres its own content, so nothing that was
     previously centred moves. */
  align-items: stretch;
  background-size: cover;
  background-position: center;
  color: #fff;
  overflow: hidden;
}
.op-hero--center { text-align: center; justify-content: center; }
.op-hero--left { text-align: left; }
.op-hero--right { text-align: right; justify-content: flex-end; }

/* The button inherits the text block's alignment unless given one of its own. */
/* Vertical placement pins the button to the inner box rather than relying on an auto
   margin.
   The margin approach only works when the flex container has free space left over, so
   it did nothing on a hero whose content already filled the height - and it failed
   silently, which is worse. Pinning is unconditional. The inner box is the positioning
   context; left and right are set so the text-align classes still decide the
   horizontal side. */
.op-hero__cta--vtop,
.op-hero__cta--vbottom {
  position: absolute;
  left: 1.5rem;
  right: 1.5rem;
}
.op-hero__cta--vtop { top: 2rem; }
.op-hero__cta--vbottom { bottom: 2rem; }

.op-hero__cta--left { text-align: left; }
.op-hero__cta--center { text-align: center; }
.op-hero__cta--right { text-align: right; }
.op-hero::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.25), rgba(0,0,0,.65));
}
/* Background layer, separate from the content so it can be transformed alone. */
.op-hero__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  will-change: transform;
}

/* Motion.
   Each animation starts and ends scaled above 1, so no edge of the image is ever
   exposed mid-cycle. alternate rather than restarting, because a jump back to the
   start is what makes a loop look like a loop. */
.op-hero__bg--zoom {
  animation: op-hero-zoom var(--op-hero-motion, 40s) ease-in-out infinite alternate;
}
@keyframes op-hero-zoom {
  from { transform: scale(1.06); }
  to   { transform: scale(1.20); }
}

.op-hero__bg--pan {
  animation: op-hero-pan var(--op-hero-motion, 40s) ease-in-out infinite alternate;
}
@keyframes op-hero-pan {
  from { transform: scale(1.14) translate3d(-2.2%, 0, 0); }
  to   { transform: scale(1.14) translate3d(2.2%, 0, 0); }
}

/* Zoom and pan together - the closest a still gets to a hovering camera. */
.op-hero__bg--drift {
  animation: op-hero-drift var(--op-hero-motion, 40s) ease-in-out infinite alternate;
}
@keyframes op-hero-drift {
  from { transform: scale(1.08) translate3d(-1.8%, -1.2%, 0); }
  to   { transform: scale(1.18) translate3d(1.8%, 1.2%, 0); }
}

/* Someone who has asked for less motion has usually asked for a reason - vestibular
   discomfort is a common one. Stop entirely rather than merely slowing down. */
@media (prefers-reduced-motion: reduce) {
  .op-hero__bg--zoom,
  .op-hero__bg--pan,
  .op-hero__bg--drift { animation: none; transform: scale(1.06); }
}

.op-hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.op-hero__inner {
  position: relative; z-index: 1;
  max-width: var(--op-max-width);
  padding: 3rem 1.5rem;
  margin: 0 auto;

  /* Full width and full height, not content size.
     As a flex item this box otherwise shrinks to fit whatever is inside it - so on a
     hero carrying only a button, the box was exactly button-sized and alignment had no
     space to work within. Height matters for the same reason: the button cannot be
     moved to the top or bottom of a box that is only as tall as the button. */
  flex: 1 1 auto;
  width: 100%;

  display: flex;
  flex-direction: column;
  justify-content: center;

  /* Belt and braces on the height. align-items:stretch on the parent should already
     give this box the hero's full height, but stretch is quietly skipped whenever the
     item ends up with a definite height of its own - and an auto margin has no free
     space to absorb in a box that fits its content exactly. */
  min-height: 100%;
  align-self: stretch;
}
.op-hero__headline { font-size: calc(3.25rem * var(--op-heading-scale)); margin: 0 0 1rem; }
.op-hero__subhead { font-size: 1.25rem; opacity: .92; margin: 0 0 2rem; }

/* progress */
.op-progress { margin: 0 0 2rem; }
.op-progress__track {
  height: 8px;
  border-radius: 999px;
  background: rgba(255,255,255,.25);
  overflow: hidden;
}
.op-progress__fill {
  height: 100%;
  background: var(--op-accent);
  transition: width .6s ease;
}
.op-progress__stats {
  display: flex; gap: 1.5rem; justify-content: center;
  margin-top: .75rem; font-size: .95rem;
}

/* buttons */
.op-btn {
  border: 0; cursor: pointer;
  border-radius: var(--op-radius);
  padding: .85rem 1.75rem;
  font: inherit; font-weight: 600;
  transition: filter .15s ease;
}
.op-btn:hover { filter: brightness(1.08); }
.op-btn--primary { background: var(--op-accent); color: #fff; }
.op-btn--outline {
  background: transparent;
  border: 1px solid var(--op-border);
  color: var(--op-text);
}
.op-btn--link { background: none; color: var(--op-accent); padding: 0; }

/* metrics */
.op-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 2rem;
}
.op-metric__value {
  font-family: var(--op-heading-font);
  font-size: 2.5rem; font-weight: 700;
  color: var(--op-primary);
}
.op-metric__label { color: var(--op-muted); margin-top: .25rem; }
.op-metric__footnote { font-size: .8rem; color: var(--op-muted); margin-top: .5rem; }

/* team, gallery */
.op-team, .op-gallery--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 2rem;
}
.op-team__photo {
  /* Capped rather than filling the column. A headshot stretched to the full width of a
     grid cell dominates the card and pushes the name and bio - the parts an investor is
     actually reading - down out of view. */
  width: 150px;
  max-width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--op-radius);
}
.op-team__name { font-weight: 600; margin-top: .75rem; }
.op-team__title { color: var(--op-muted); font-size: .9rem; }
.op-gallery__item img { width: 100%; border-radius: var(--op-radius); }

/* video */
.op-video__frame { position: relative; padding-top: 56.25%; /* overridden inline per block */ }
.op-video__frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border-radius: var(--op-radius);
}
.op-video__player { width: 100%; border-radius: var(--op-radius); }
.op-video__caption { color: var(--op-muted); margin-top: .75rem; }

/* faq, timeline */
.op-faq__item {
  border-bottom: 1px solid var(--op-border-accent, var(--op-border));
  padding: 1rem 0;
}
.op-faq__item summary { cursor: pointer; font-weight: 600; }
.op-faq__answer { margin-top: .75rem; color: var(--op-muted); }

.op-timeline { list-style: none; padding: 0; margin: 0; }
.op-timeline__item {
  display: flex; gap: 1rem;
  padding-bottom: 2rem;
  border-left: 2px solid var(--op-border);
  padding-left: 1.5rem; margin-left: .5rem;
}
.op-timeline__item.is-complete { border-left-color: var(--op-accent); }
.op-timeline__label { font-weight: 600; }
.op-timeline__date { color: var(--op-muted); font-size: .9rem; }

/* data room */
.op-dataroom { list-style: none; padding: 0; }
.op-dataroom__item {
  display: flex; align-items: center; gap: 1rem;
  padding: .9rem 0;
  border-bottom: 1px solid var(--op-border);
}
.op-dataroom__name { flex: 1; }
.op-dataroom__size { color: var(--op-muted); font-size: .85rem; }
.op-dataroom__gate {
  /* Tinted from the page's own text colour rather than given a fixed surface.
     An explicit light background needed a dark text colour to sit on it, and --op-text
     is white on a dark theme - so the previous version put white on white. Deriving
     both from currentColor cannot produce that: the panel is always a faint wash of
     whatever the text already is. */
  background: color-mix(in srgb, currentColor 6%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  border-radius: var(--op-radius);
  padding: 2rem;
  text-align: center;
}
.op-dataroom__gate p { margin: 0 0 1.25rem; }
.op-dataroom__gate p { margin: 0 0 1.25rem; }

/* cta, disclosure */
.op-cta { text-align: center; background: var(--op-surface); }
.op-cta__headline { font-size: calc(2.25rem * var(--op-heading-scale)); }
.op-disclosure {
  font-size: .8rem;
  color: var(--op-muted);
  border-top: 1px solid var(--op-border);
}

/* sticky invest bar */
.op-stickybar {
  position: sticky; bottom: 0; z-index: 20;
  background: var(--op-bg);
  border-top: 1px solid var(--op-border);
  box-shadow: 0 -4px 20px rgba(0,0,0,.06);
}
.op-stickybar__inner {
  max-width: var(--op-max-width);
  margin: 0 auto;
  padding: 1rem 1.5rem;
  display: flex; align-items: center; gap: 1.5rem;
}
.op-stickybar__stats { flex: 1; }
.op-stickybar__min { color: var(--op-muted); font-size: .9rem; }

/* deal grid, admin */
.op-page, .op-admin-body { max-width: 1200px; margin: 0 auto; padding: 2rem 1.5rem; }
.op-dealgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}
.op-dealcard {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 1.5rem;
  cursor: pointer;
}
.op-dealcard:hover { box-shadow: 0 4px 16px rgba(0,0,0,.08); }
.op-dealcard__stats {
  display: flex; justify-content: space-between;
  margin-top: .75rem; font-size: .9rem; color: #64748B;
}
.op-filters { margin: 1.5rem 0; }
.op-help { color: #64748B; max-width: 70ch; }
.op-row--attention { background: #FEF3C7; }
.op-reconcile-card { margin-top: 1.5rem; }
.op-loading, .op-empty { padding: 4rem; text-align: center; }

/* first-run setup guidance on the landing page */
.op-setup__code {
  background: #0F172A;
  color: #E2E8F0;
  padding: 1rem;
  border-radius: 6px;
  font-size: .78rem;
  overflow-x: auto;
  white-space: pre;
}
.op-setup__links { display: flex; gap: .75rem; margin-top: 1.5rem; }

/* CRM block editors */
.op-blockeditor { display: flex; flex-direction: column; gap: 1rem; }
.op-blockeditor__preview {
  position: relative;
  height: 190px;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.op-blockeditor__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.25), rgba(0,0,0,.65));
}
.op-blockeditor__previewinner { position: relative; z-index: 1; text-align: center; color: #fff; padding: 1rem; }
.op-blockeditor__headline { font-size: 1.6rem; font-weight: 600; }
.op-blockeditor__subhead { opacity: .9; margin-top: .35rem; }
.op-blockeditor__row { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.op-blockeditor__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}

/* section tabs */
.op-tabs {
  position: sticky;
  top: 0;
  z-index: 15;
  background: var(--op-bg);
  border-bottom: 1px solid var(--op-border);
}
.op-tabs__inner {
  max-width: var(--op-max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  gap: .25rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.op-tabs__inner::-webkit-scrollbar { display: none; }
.op-tabs__tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 1rem .9rem;
  font: inherit;
  font-size: .95rem;
  color: var(--op-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color .15s ease, border-color .15s ease;
}
.op-tabs__tab:hover { color: var(--op-text); }
.op-tabs__tab.is-active {
  color: var(--op-accent);
  border-bottom-color: var(--op-accent);
  font-weight: 600;
}
.op-tabs__tab:focus-visible {
  outline: 2px solid var(--op-accent);
  outline-offset: -2px;
}
.op-tabpanel:focus { outline: none; }

/* feature video - centred inside a full-bleed tinted band */
.op-videoband {
  background: var(--op-surface);
  border-bottom: 1px solid var(--op-border);
}
.op-video--feature {
  /* 720px default. The frame is deliberately narrower than the 1120px content
     column: a talking-head video blown to full width reads as a banner, and the
     gutters give the eye somewhere to rest before the tab strip. */
  max-width: var(--op-video-width, 720px);
  margin: 0 auto;
  padding: 2.75rem 1.5rem 2.25rem;
  text-align: center;
}
.op-video--feature .op-video__frame {
  position: relative;
  border-radius: var(--op-radius);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--op-border-accent, var(--op-border));
}
.op-video--feature .op-video__frame > iframe,
.op-video--feature .op-video__frame > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}
.op-video__eyebrow {
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--op-muted);
  margin-bottom: .75rem;
}
.op-video--feature .op-video__caption {
  color: var(--op-muted);
  font-size: .9rem;
  margin-top: .9rem;
}

/* body: tab content left, sticky invest rail right */
.op-body {
  max-width: var(--op-max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 2.5rem;
  align-items: start;
}
.op-body--notabs { padding-top: 2rem; }
.op-body .op-section { max-width: none; padding-left: 0; padding-right: 0; }

/* 5rem clears the sticky tab strip so the panel never hides it */
.op-body__rail { position: sticky; top: 5rem; padding: 2rem 0; }

/* external-link video card */
.op-video__link {
  display: block;
  background-size: cover;
  background-position: center;
  background-color: var(--op-primary);
  text-decoration: none;
  cursor: pointer;
}
.op-video__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.55));
}
.op-video__play {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 68px; height: 68px;
  border-radius: 50%;
  background: rgba(255,255,255,.94);
  color: var(--op-primary);
  display: flex; align-items: center; justify-content: center;
  transition: transform .15s ease;
}
.op-video__link:hover .op-video__play { transform: translate(-50%, -50%) scale(1.06); }
.op-video__linkhost {
  position: absolute; bottom: .85rem; right: 1rem;
  display: inline-flex; align-items: center; gap: .35rem;
  background: rgba(0,0,0,.55);
  color: #fff;
  font-size: .75rem;
  padding: .3rem .6rem;
  border-radius: 999px;
}

.op-investpanel {
  background: var(--op-investpanel-bg, var(--op-primary));
  color: var(--op-investpanel-text, #fff);
  border-radius: calc(var(--op-radius) * 1.5);
  padding: 1.75rem;
}
.op-investpanel__title { font-family: var(--op-heading-font); font-size: 1.4rem; font-weight: 700; margin-bottom: 1.25rem; }
.op-investpanel__label { display: block; font-size: .95rem; font-weight: 600; margin-bottom: .5rem; }
.op-investpanel__input {
  width: 100%;

  /* width:100% plus horizontal padding overflows the card without this. The panel
     is the one place it shows badly, because the card has padding of its own. */
  box-sizing: border-box;
  /* Derived from the text colour rather than fixed white, so the field stays visible
     when the panel is themed light. */
  background: color-mix(in srgb, currentColor 12%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  border-radius: var(--op-radius);
  padding: .8rem 1rem;
  color: inherit;
  font: inherit;
  font-size: 1rem;
}
.op-investpanel__input::placeholder { color: color-mix(in srgb, currentColor 55%, transparent); }
.op-investpanel__input:focus { outline: 2px solid var(--op-accent); outline-offset: 1px; }
.op-investpanel__rule {
  border-top: 1px dashed color-mix(in srgb, currentColor 30%, transparent);
  margin: 1.5rem 0;
}
.op-investpanel__total { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.op-investpanel__totallabel { font-weight: 700; font-size: 1.05rem; line-height: 1.3; }
.op-investpanel__totalvalue { font-weight: 700; font-size: 1.35rem; white-space: nowrap; }
.op-investpanel__meta { font-size: .82rem; opacity: .75; margin-top: .4rem; }
.op-investpanel__warn {
  margin-top: .9rem;
  font-size: .85rem;
  background: rgba(255,255,255,.12);
  border-radius: var(--op-radius);
  padding: .6rem .8rem;
}
.op-investpanel__cta {
  width: 100%;
  margin-top: 1.5rem;
  background: var(--op-investbtn-bg, #fff);
  color: var(--op-investbtn-text, var(--op-primary));
  border: 0;
  border-radius: var(--op-radius);
  padding: .9rem 1rem;
  font: inherit;
  font-size: 1rem;
  cursor: pointer;
}
.op-investpanel__cta:hover:not(:disabled) { filter: brightness(.95); }
.op-investpanel__cta:disabled { opacity: .55; cursor: not-allowed; }
.op-investpanel__note { margin-top: .9rem; font-size: .78rem; opacity: .7; line-height: 1.5; }

.op-stickybar--narrowonly { display: none; }

@media (max-width: 900px) {
  .op-body { grid-template-columns: 1fr; gap: 1.5rem; }
  .op-body__rail { position: static; padding: 0 0 2rem; }
  .op-body--notabs > div:first-child { display: none; }
  .op-stickybar--narrowonly { display: block; }
}

/* ---- split auth shell: form left, admin artwork right ---- */
.op-auth {
  display: grid;

  /* The form is capped at 380px, so a 40% column was mostly empty white on any wide
     screen - and every pixel it took was a pixel the artwork lost, which is why the
     background looked crowded. Clamping the column keeps the form comfortable without
     letting it grow past what it needs. */
  grid-template-columns: clamp(400px, 30%, 520px) 1fr;
  min-height: 100vh;
}
.op-auth__form {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
  background: #fff;
}
.op-auth__formInner { width: 100%; max-width: 380px; }

.op-auth__brand { display: flex; align-items: center; gap: .65rem; margin-bottom: 3rem; }
.op-auth__logo { width: 36px; height: 36px; object-fit: contain; }
.op-auth__company { font-weight: 600; font-size: 1.05rem; }

.op-auth__title { font-size: 1.7rem; margin: 0 0 .4rem; letter-spacing: -0.02em; }
.op-auth__sub { color: #64748B; font-size: .92rem; margin: 0 0 2rem; }
.op-auth__sub a { color: #2563EB; font-weight: 600; text-decoration: none; }

.op-auth__label { display: block; font-size: .85rem; font-weight: 500; margin: 0 0 .4rem; }
.op-auth__input {
  width: 100%;
  border: 1px solid #CBD5E1;
  border-radius: 6px;
  padding: .6rem .75rem;
  font: inherit;
  margin-bottom: 1.1rem;
}
.op-auth__input:focus { outline: 2px solid #2563EB; outline-offset: -1px; border-color: #2563EB; }
.op-auth__input--code {
  font-family: ui-monospace, monospace;
  font-size: 1.4rem;
  letter-spacing: .4em;
  text-align: center;
}
.op-auth__check { display: flex; align-items: center; gap: .5rem; font-size: .9rem; margin-bottom: 1.5rem; }

.op-auth__submit {
  width: 100%;
  background: #0F172A;
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: .75rem;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
  display: block;
  text-align: center;
  text-decoration: none;
}
.op-auth__submit:hover { filter: brightness(1.15); }
.op-auth__submit--link { margin-top: 1.5rem; }

.op-auth__error {
  background: #FEF2F2;
  border: 1px solid #FCA5A5;
  color: #991B1B;
  border-radius: 6px;
  padding: .7rem .85rem;
  font-size: .88rem;
  margin-bottom: 1.25rem;
}
.op-auth__fielderror { color: #DC2626; font-size: .82rem; display: block; margin: -.85rem 0 1rem; }
.op-auth__meta { margin-top: 1.25rem; font-size: .88rem; }
.op-auth__meta a { color: #2563EB; text-decoration: none; }
.op-auth__legal { margin-top: 2.5rem; font-size: .75rem; color: #94A3B8; line-height: 1.6; }

/* artwork panel */
.op-auth__art {
  position: relative;

  /* cover crops to fill, which on a tall narrow column throws away most of the
     composition. Kept, because letterboxing a login screen looks like a mistake - but
     anchored high so the logo and headline survive the crop rather than the empty
     lower half of the chart. */
  background-size: cover;
  background-position: center 35%;
  color: #fff;
  display: flex;
  align-items: flex-end;
  padding: 3rem;
}
.op-auth__artInner { position: relative; z-index: 1; width: 100%; text-align: center; }
.op-auth__eyebrow {
  font-size: .78rem; letter-spacing: .18em; text-transform: uppercase;
  opacity: .8; margin-bottom: .75rem;
}
.op-auth__headline {
  font-size: 1.5rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 500;
}
.op-auth__subhead { opacity: .85; max-width: 46ch; margin: .75rem auto 0; font-size: .95rem; }
.op-auth__footer {
  margin-top: 2.5rem; font-size: .82rem; letter-spacing: .08em;
  opacity: .75; line-height: 1.9;
}
.op-auth__poweredby { text-transform: uppercase; font-size: .75rem; }

/* the artwork is decoration - drop it before the form gets cramped */
@media (max-width: 900px) {
  .op-auth { grid-template-columns: 1fr; min-height: auto; }
  .op-auth__art { display: none; }
  .op-auth__form { padding: 2rem 1.25rem; min-height: 100vh; }
}

/* ---- focused auth card over full-bleed artwork (MFA step) ---- */
.op-authfocus {
  position: relative;
  min-height: 100vh;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem 8rem;
}
.op-authfocus__scrim {
  position: absolute; inset: 0;
  background: rgba(4, 16, 30, .35);
}
.op-authfocus__card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 440px;
  background: #fff;
  border-radius: 10px;
  padding: 2.75rem 2.5rem;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
}
.op-authfocus__footer {
  position: absolute;
  left: 0; right: 0; bottom: 2.5rem;
  z-index: 1;
  text-align: center;
  color: #fff;
}
.op-authfocus__support {
  margin-top: .6rem;
  font-size: .85rem;
  letter-spacing: .08em;
  opacity: .8;
}

.op-otp__title { font-size: 1.45rem; margin: 0 0 .75rem; color: #0F172A; }
.op-otp__sub { color: #64748B; font-size: .9rem; margin: 0 0 .5rem; line-height: 1.6; }
.op-otp__sub a { color: #0F172A; font-weight: 600; text-decoration: none; }
.op-otp__account { color: #334155; font-weight: 500; }

.op-otp__boxes {
  display: flex;
  gap: .5rem;
  justify-content: center;
  margin: 1.75rem 0;
}
.op-otp__box {
  width: 52px;
  height: 56px;
  border: 1px solid #E2E8F0;
  background: #F1F5F9;
  border-radius: 8px;
  text-align: center;
  font-size: 1.4rem;
  font-weight: 600;
  color: #0F172A;
}
.op-otp__box:focus {
  outline: none;
  border-color: #0F172A;
  background: #fff;
  box-shadow: 0 0 0 3px rgba(15, 23, 42, .08);
}
.op-otp__submit {
  width: 100%;
  background: #0F172A;
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: .8rem;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.op-otp__submit:hover { filter: brightness(1.2); }
.op-otp__meta { margin-top: 1.5rem; font-size: .85rem; color: #64748B; }
.op-otp__meta a { color: #0F172A; font-weight: 600; text-decoration: none; }

@media (max-width: 520px) {
  .op-otp__box { width: 42px; height: 50px; font-size: 1.2rem; }
  .op-authfocus__card { padding: 2rem 1.5rem; }
  .op-authfocus__footer { display: none; }
}

/* MFA enrolment */
.op-enrol__qr {
  display: flex;
  justify-content: center;
  margin: 1.5rem 0 1.25rem;
}
.op-enrol__qr img {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 8px;
  background: #fff;
}
.op-enrol__secret {
  display: inline-block;
  margin-top: .4rem;
  font-family: ui-monospace, monospace;
  font-size: .95rem;
  letter-spacing: .1em;
  background: #F1F5F9;
  border-radius: 6px;
  padding: .35rem .6rem;
  color: #0F172A;
}

/* recovery codes, shown once */
.op-recovery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .5rem;
  margin: 1.5rem 0 1rem;
}
.op-recovery__code {
  background: #F1F5F9;
  border-radius: 6px;
  padding: .55rem;
  font-family: ui-monospace, monospace;
  font-size: .95rem;
  color: #0F172A;
  letter-spacing: .05em;
}
.op-recovery__warn { color: #B45309; font-weight: 500; }

/* rail on the left: swap the visual order, leave the DOM order alone so the
   reading and tab sequence still reaches the content before the form */
.op-body--railleft { grid-template-columns: 360px minmax(0, 1fr); }
.op-body--railleft .op-tabpanel { order: 2; }
.op-body--railleft .op-body__rail { order: 1; }

/* video sharing the rail with the invest panel */
.op-body__railmedia { margin-bottom: 1.25rem; }
.op-body__railmedia .op-video--feature { max-width: 100%; padding: 0; }
.op-body__railmedia .op-video__eyebrow { text-align: left; }

@media (max-width: 900px) {
  .op-body--railleft { grid-template-columns: 1fr; }
  .op-body--railleft .op-tabpanel,
  .op-body--railleft .op-body__rail { order: initial; }
}

/* ---- pitch row: narrative one side, video the other ---- */
.op-pitch {
  max-width: var(--op-max-width);
  margin: 0 auto;
  padding: 4rem 2rem 3rem;
  display: grid;

  /* The share is set per offering and arrives as --op-pitch-cols on the element.
     Falling back to an even split keeps the row working when no video is paired. */
  grid-template-columns: var(--op-pitch-cols, minmax(0, 1fr) minmax(0, 1fr));
  gap: 2.5rem;
  align-items: center;
}
/* order, not markup order: the copy still comes first for a screen reader */
.op-pitch--medialeft .op-pitch__text { order: 2; }
.op-pitch--medialeft .op-pitch__media { order: 1; }

.op-pitch__media .op-video--feature { max-width: 100%; padding: 0; }
.op-pitch__media .op-video__frame { border: 1px solid var(--op-border-accent, var(--op-border)); }

.op-pitch__headline {
  font-size: calc(2.9rem * var(--op-heading-scale));
  line-height: 1.12;
  letter-spacing: -0.025em;
  margin: 0 0 1.5rem;
}
.op-pitch__body { font-size: 1.02rem; line-height: 1.75; color: var(--op-text); }
.op-pitch__body p { margin: 0 0 1.1rem; }
.op-pitch__body ul { margin: 0 0 1.1rem; padding-left: 1.25rem; }
.op-pitch__body li { margin-bottom: .4rem; }

/* button and the two or three facts that decide whether they keep reading */
.op-pitch__action {
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
  margin-top: 2rem;

  /* No wrapping above the mobile breakpoint. The button holds its size and the facts
     give up width instead - a fact that has gone narrow still reads, whereas the same
     row broken over two lines stops looking like a row at all. */
  flex-wrap: nowrap;
}
.op-pitch__cta { flex: 0 0 auto; }
.op-pitch__cta {
  background: var(--op-accent);
  color: #fff;
  border: 0;
  border-radius: var(--op-radius);
  padding: 1.05rem 2.25rem;
  font: inherit;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.op-pitch__cta:hover { filter: brightness(1.08); }

.op-pitch__fact {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-left: 1.25rem;
  border-left: 1px solid var(--op-border-accent, var(--op-border));

  /* Shrinkable, so a tight row narrows the facts rather than breaking the line. */
  min-width: 0;
  flex: 0 1 auto;
}
.op-pitch__fact:first-of-type { border-left: 0; padding-left: 0; }
.op-pitch__factlabel,
.op-pitch__factvalue { white-space: nowrap; }
.op-pitch__factlabel { font-size: .8rem; color: var(--op-muted); }
.op-pitch__factvalue { font-weight: 700; font-size: 1.05rem; margin-top: .15rem; }

.op-pitch__footnote { margin-top: 1.75rem; color: var(--op-muted); font-size: .92rem; }

@media (max-width: 900px) {
  /* One column, copy first, video beneath it. Stated without the variable so the
     per-offering share does not reach this width. */
  .op-pitch { grid-template-columns: minmax(0, 1fr); gap: 2rem; padding: 2.5rem 1.25rem; }
  .op-pitch__media { order: 2; }
  .op-pitch__text { order: 1; }
  .op-pitch--medialeft .op-pitch__text,
  .op-pitch--medialeft .op-pitch__media { order: initial; }
  .op-pitch__headline { font-size: calc(2.1rem * var(--op-heading-scale)); }
  .op-pitch__action { gap: 1.25rem; flex-wrap: wrap; }
}

/* pitch with no paired video: one column rather than an empty half */
.op-pitch--solo { grid-template-columns: minmax(0, 820px); justify-content: center; }

/* ---- offering builder ---- */
.op-adminhead {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.5rem; flex-wrap: wrap;
}
.op-adminhead h1 { margin: 0 0 .25rem; }
.op-mono { font-family: ui-monospace, monospace; font-size: .85rem; }
.op-rule { border: 0; border-top: 1px solid #E2E8F0; margin: 1.25rem 0; }
.op-createcard { margin-top: 1.5rem; max-width: 640px; }

.op-contenteditor {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
.op-contenteditor__list {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: .75rem;
  background: #fff;
  position: sticky;
  top: 1rem;
}
.op-contenteditor__listhead,
.op-blockeditor__listhead {
  display: flex; align-items: center; justify-content: space-between;
  font-weight: 600; font-size: .9rem; margin-bottom: .5rem;
}
.op-contenteditor__panel {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 1.5rem;
  background: #fff;
  min-height: 400px;
}

.op-palette {
  display: grid; grid-template-columns: 1fr 1fr; gap: .35rem;
  padding: .5rem; margin-bottom: .75rem;
  background: #F8FAFC; border-radius: 6px;
}
.op-palette__item {
  border: 1px solid #E2E8F0; background: #fff; border-radius: 6px;
  padding: .45rem; font: inherit; font-size: .82rem; cursor: pointer;
}
.op-palette__item:hover { border-color: #2563EB; color: #2563EB; }

.op-blockrow {
  display: flex; align-items: center; gap: .5rem;
  padding: .6rem .5rem; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent;
}
.op-blockrow:hover { background: #F8FAFC; }
.op-blockrow.is-selected { background: #EFF6FF; border-color: #BFDBFE; }
.op-blockrow__main { flex: 1; min-width: 0; }
.op-blockrow__name { font-size: .9rem; font-weight: 500; }
.op-blockrow__meta { font-size: .75rem; display: flex; gap: .4rem; margin-top: .1rem; }
.op-blockrow__tab {
  background: #E0E7FF; color: #3730A3; border-radius: 999px; padding: 0 .45rem;
}
.op-blockrow__hidden { color: #B45309; }
.op-blockrow__actions { display: flex; gap: .15rem; }
.op-blockrow__actions button {
  border: 0; background: none; cursor: pointer; color: #64748B;
  width: 22px; height: 22px; border-radius: 4px; font-size: .85rem;
}
.op-blockrow__actions button:hover:not(:disabled) { background: #E2E8F0; color: #0F172A; }
.op-blockrow__actions button:disabled { opacity: .3; cursor: default; }
.op-blockrow__remove:hover { background: #FEE2E2 !important; color: #B91C1C !important; }

.op-factrow {
  display: flex; gap: .5rem; align-items: center; margin-bottom: .5rem;
}
.op-factrow > :not(:last-child) { flex: 1; }

@media (max-width: 1000px) {
  .op-contenteditor { grid-template-columns: 1fr; }
  .op-contenteditor__list { position: static; }
}

/* offering settings */
.op-settings {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 1.25rem;
  align-items: start;
}
.op-settings__card--wide { grid-column: 1 / -1; }
.op-settings__card h3 { margin: 0 0 1rem; font-size: 1.05rem; }
.op-settings__card .op-blockeditor__grid { margin-bottom: .5rem; }

.op-problems { margin: .25rem 0 0; padding-left: 1.1rem; }
.op-problems li { margin-bottom: .2rem; }

.op-publishrow {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
}
.op-publishrow__status { font-size: .95rem; margin-bottom: .35rem; }

/* tranches */
.op-tranche {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: .9rem;
}
.op-tranche.is-inactive { opacity: .6; background: #F8FAFC; }
.op-tranche__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: .75rem;
}
.op-tranche__kind {
  font-weight: 600; margin-right: .5rem;
}

/* eligibility rule groups */
.op-rules {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: .85rem 1rem 1rem;
  margin: 0 0 1rem;
}
.op-rules legend {
  font-size: .78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #64748B;
  padding: 0 .4rem;
}
.op-rule__item {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  padding: .45rem 0;
}
.op-rule__item.is-locked { opacity: .75; }
.op-rule__why {
  font-size: .78rem;
  color: #64748B;
  margin-top: .15rem;
  line-height: 1.5;
}

/* unsaved changes indicator */
.op-dirty {
  font-size: .82rem;
  color: #B45309;
  background: #FEF3C7;
  border-radius: 999px;
  padding: .2rem .7rem;
  white-space: nowrap;
}

/* integrations status */
.op-integrations {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}
.op-integration__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: .6rem;
}
.op-integration__name { font-weight: 600; }
.op-integration__detail { font-size: .88rem; line-height: 1.6; }
.op-integration__hook { margin-top: .5rem; font-size: .78rem; }

/* signed-in chrome */
.op-whoami { font-size: .85rem; opacity: .85; }
.op-signout { color: inherit; text-decoration: none; font-size: .88rem; opacity: .9; }
.op-signout:hover { opacity: 1; text-decoration: underline; }

.op-topbar { background: #0F172A; color: #fff; }
.op-topbar__inner {
  max-width: var(--op-max-width, 1120px);
  margin: 0 auto;
  padding: .6rem 1.5rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.op-topbar__right { display: flex; align-items: center; gap: 1.25rem; }
.op-topbar__link { color: #fff; text-decoration: none; font-size: .88rem; opacity: .9; }
.op-topbar__link:hover { opacity: 1; text-decoration: underline; }

/* integration settings editor */
.op-setting {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 150px 80px;
  gap: 1rem;
  align-items: center;
  padding: .65rem 0;
  border-bottom: 1px solid #F1F5F9;
}
.op-setting:last-child { border-bottom: 0; }
.op-setting__label { min-width: 0; }
.op-setting__label > div:first-child { font-size: .92rem; font-weight: 500; }

/* The setting key, which is long and has no spaces to break at.
   A monospace identifier like MailerSend:Templates:AccreditationPending is a single
   unbreakable token as far as the browser is concerned, so without an explicit rule it
   runs straight out of its 260px column and under the input beside it. Breaking on the
   colons keeps it readable; anywhere is better than overflowing. */
.op-setting__label .op-mono {
  overflow-wrap: anywhere;
  word-break: break-word;
  line-height: 1.35;
  display: block;
}
.op-setting__meta { display: flex; flex-direction: column; gap: .2rem; font-size: .78rem; }

@media (max-width: 1000px) {
  .op-setting { grid-template-columns: 1fr; gap: .35rem; }
}

/* file-picker label styled as a button */
.op-uploadbtn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  border: 1px solid var(--rz-primary, #2563EB);
  color: var(--rz-primary, #2563EB);
  border-radius: 4px;
  padding: .45rem .9rem;
  font-size: .875rem;
  cursor: pointer;
  user-select: none;
}
.op-uploadbtn:hover { background: rgba(37, 99, 235, .06); }
.op-uploadbtn.is-busy { opacity: .5; pointer-events: none; }

/* branding asset preview */
.op-brandasset {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
  margin: 1rem 0;
}
.op-brandasset__preview {
  width: 200px;
  height: 120px;
  flex: 0 0 auto;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
}
.op-brandasset__preview--logo {
  width: 72px;
  height: 72px;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

/* disclosure editor */
.op-disclosure__readonly {
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 1rem;
  background: #F8FAFC;
  font-size: .9rem;
  line-height: 1.7;
  max-height: 400px;
  overflow-y: auto;
}
.op-disclosure__templates {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

/* preview banner */
.op-previewbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: #B45309;
  color: #fff;
  padding: .5rem 1.25rem;
  font-size: .88rem;
  font-weight: 500;
  letter-spacing: .02em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.op-previewbar__text span { opacity: .85; font-weight: 400; margin-left: .35rem; }
.op-previewbar__actions { display: flex; gap: 1.1rem; }
.op-previewbar__actions a {
  color: #fff;
  text-decoration: none;
  font-weight: 400;
  border-bottom: 1px solid rgba(255, 255, 255, .45);
}
.op-previewbar__actions a:hover { border-bottom-color: #fff; }

/* the tab strip sticks below the preview bar rather than under it */
.op-previewbar ~ .op-root .op-tabs { top: 2.5rem; }

/* admin header brand */
.op-adminbrand {
  display: flex;
  align-items: center;
  gap: .75rem;

  /* Clears the left edge and leaves room for a logo beside the name. Matches the
     sidebar's own inset so the two line up rather than sitting at different depths. */
  padding-left: 1.25rem;
}
.op-adminbrand__logo {
  width: 28px;
  height: 28px;
  object-fit: contain;
  border-radius: 4px;
  background: rgba(255, 255, 255, .12);
}
.op-adminbrand__name {
  font-size: 1rem;
  font-weight: 500;
  white-space: nowrap;
}

/* pasted embed markup - force the player to fill the frame whatever size it declares */
.op-video__embed > iframe,
.op-video__embed > video,
.op-video__embed > div > iframe {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  border: 0;
}

/* hero, bar variant */
.op-herobar {
  background: var(--op-herobar-bg, var(--op-primary));
  color: #fff;
  padding: 1.1rem 1.5rem;
}
.op-herobar__inner {
  max-width: var(--op-max-width);
  margin: 0 auto;
  text-align: center;
}
.op-herobar__name {
  font-family: var(--op-heading-font);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.op-herobar__meta {
  font-size: .88rem;
  opacity: .85;
  margin-top: .2rem;
}
.op-herobar__sep { margin: 0 .4rem; opacity: .6; }
.op-herobar__progress {
  max-width: 420px;
  margin: .7rem auto 0;
  height: 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .22);
  overflow: hidden;
}
.op-herobar__progress > div {
  height: 100%;
  background: var(--op-accent);
  transition: width .4s ease;
}

/* embed preview in the editor */
.op-embedpreview { margin: .75rem 0 1rem; }
.op-embedpreview__label {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #64748B;
  margin-bottom: .35rem;
}
.op-embedpreview__frame {
  position: relative;
  padding-top: 45%;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  overflow: hidden;
  background: #0F172A;
}
.op-embedpreview__frame iframe,
.op-embedpreview__frame video,
.op-embedpreview__frame > div > iframe {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  border: 0;
}

/* video width cap - see SizerStyle for why this is a separate element */
.op-video__sizer { width: 100%; }


/* Scaled document frames.
   No !important on width or height here: the size arrives as an inline style, and an
   important declaration in a stylesheet outranks inline - which is exactly what stopped
   the design width from taking effect. */
.op-video__frame[data-frame-scale] > iframe {
  position: absolute;
  top: 0;
  left: 0;
  right: auto;
  bottom: auto;
  transform-origin: 0 0;
}

/* framed content: loading state */
.op-video__loading {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: #0B1220;
  border-radius: var(--op-radius);
}
.op-video__frame--pending .op-video__loading { display: flex; }

/* The iframe fades in rather than appearing abruptly over the spinner. */
.op-video__frame--pending > iframe { opacity: 0; }
.op-video__frame > iframe { opacity: 1; transition: opacity .3s ease; }

.op-video__spinner {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .18);
  border-top-color: var(--op-accent, #76B900);
  animation: op-spin .8s linear infinite;
}
@keyframes op-spin { to { transform: rotate(360deg); } }

/* Respects a stated preference for less motion - a spinning element is exactly the
   kind of thing that setting exists for. */
@media (prefers-reduced-motion: reduce) {
  .op-video__spinner { animation-duration: 2.4s; }
  .op-video__frame > iframe { transition: none; }
}

/* theme editor: swatch rows */
.op-swatch {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .6rem 0;
  border-bottom: 1px solid #F1F5F9;
}
.op-swatch:last-child { border-bottom: 0; }
.op-swatch__name { font-weight: 600; font-size: .92rem; }
.op-swatch__note { font-size: .8rem; color: #64748B; margin-top: .1rem; }

/* theme editor: live preview, styled entirely from the theme's own variables */
.op-themepreview {
  border: 1px solid #E2E8F0;
  border-radius: 10px;
  overflow: hidden;
  background: var(--op-bg);
  font-family: var(--op-body-font);
}
.op-themepreview__hero {
  background: var(--op-herobar-bg, var(--op-primary));
  color: #fff;
  text-align: center;
  padding: .9rem 1rem;
  font-family: var(--op-heading-font);
  font-weight: 700;
}
.op-themepreview__body {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 1.5rem;
  padding: 1.75rem;
}
.op-themepreview__headline {
  font-family: var(--op-heading-font);
  color: var(--op-text);
  font-size: calc(1.4rem * var(--op-heading-scale));
  margin: 0 0 .6rem;
}
.op-themepreview__text { color: var(--op-text); font-size: .92rem; margin: 0 0 1rem; }
.op-themepreview__muted { color: var(--op-muted); }
.op-themepreview__btn {
  display: inline-block;
  background: var(--op-accent);
  color: #fff;
  border-radius: var(--op-radius);
  padding: .6rem 1.4rem;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .06em;
}
.op-themepreview__panel {
  background: var(--op-investpanel-bg, var(--op-primary));
  color: var(--op-investpanel-text, #fff);
  border-radius: calc(var(--op-radius) * 1.5);
  padding: 1.25rem;
}
.op-themepreview__field {
  background: color-mix(in srgb, currentColor 12%, transparent);
  border-radius: var(--op-radius);
  padding: .6rem .8rem;
  margin-top: .8rem;
  font-size: .85rem;
  opacity: .75;
}

/* login support links: readable as links without shouting */
.op-auth__support {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .3);
}
.op-auth__support:hover { border-bottom-color: rgba(255, 255, 255, .8); }

/* branding screen: font preview */
.op-fontpreview {
  margin-top: 1rem;
  padding: 1.1rem 1.25rem;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  background: #F8FAFC;
}
.op-fontpreview__heading {
  font-family: var(--portal-heading-font);
  font-size: 1.35rem;
  font-weight: 700;
  margin-bottom: .35rem;
}
.op-fontpreview__body {
  font-family: var(--portal-body-font);
  font-size: .95rem;
  color: #475569;
}

/* theme editor: hex entry beside each picker */
.op-swatch__hex {
  width: 108px;
  flex: 0 0 auto;
  font-family: ui-monospace, monospace;
  font-size: .85rem;
}

/* theme preview: the invest button, so the button swatches have something to show */
.op-themepreview__cta {
  margin-top: .8rem;
  background: var(--op-investbtn-bg, #fff);
  color: var(--op-investbtn-text, var(--op-primary));
  border-radius: var(--op-radius);
  padding: .6rem 1rem;
  text-align: center;
  font-size: .88rem;
  font-weight: 600;
}

/* data room editor */
.op-dataroom__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 1.5rem 0 .5rem;
}
.op-dataroom__head h4 { margin: 0; font-size: .95rem; }
.op-dataroom__list { border: 1px solid #E2E8F0; border-radius: 8px; overflow: hidden; }
.op-dataroom__row {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem .85rem;
  border-bottom: 1px solid #F1F5F9;
}
.op-dataroom__row:last-child { border-bottom: 0; }
.op-dataroom__row.is-on { background: #F0F7FF; }
.op-dataroom__file { flex: 1 1 auto; min-width: 0; }
.op-dataroom__name {
  font-size: .9rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.op-dataroom__meta { font-size: .78rem; color: #64748B; margin-top: .1rem; }
.op-dataroom__locked { color: #B45309; margin-left: .4rem; }

/* team block editor - named apart from .op-team, which the offer page renderer owns */
.op-teamedit { display: grid; gap: 1rem; margin: 1rem 0; }
.op-teamedit__card { padding: 1.1rem 1.25rem; }
.op-teamedit__head {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: .9rem;
}
.op-teamedit__photo {
  width: 72px;
  height: 72px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: #E2E8F0;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: #64748B;
  font-size: 1.15rem;
}
.op-teamedit__photoactions { flex: 1 1 auto; min-width: 0; }
.op-teamedit__photoactions .op-help { margin: .4rem 0 0; }
.op-teamedit__order { display: flex; gap: .1rem; flex: 0 0 auto; }

.op-help--warn { color: #B45309; }

/* FAQ editor - named apart from .op-faq, which the renderer owns */
.op-faqedit { display: grid; gap: .75rem; margin: 1rem 0; }
.op-faqedit__card { padding: .9rem 1rem; }
.op-faqedit__head {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .6rem;
}
.op-faqedit__num {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #E2E8F0;
  color: #475569;
  font-size: .72rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.op-faqedit__q { flex: 1 1 auto; min-width: 0; font-weight: 500; }
.op-faqedit__a { width: 100%; }
.op-faqedit__actions { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }

/* the offering's public URL, in admin */
.op-publiclink {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin-top: .15rem;
}
.op-publiclink__url {
  font-family: ui-monospace, monospace;
  font-size: .82rem;
  color: var(--rz-primary, #2563EB);
  text-decoration: none;
  border-bottom: 1px solid rgba(37, 99, 235, .3);
}
.op-publiclink__url:hover { border-bottom-color: currentColor; }
.op-publiclink--pending .op-publiclink__url {
  color: #64748B;
  border-bottom: 0;
}
.op-publiclink__note {
  font-size: .74rem;
  color: #94A3B8;
  text-transform: uppercase;
  letter-spacing: .05em;
}

/* subscribe page */
.op-subscribe {
  max-width: var(--op-max-width, 1280px);
  margin: 0 auto;
  padding: 2.5rem 2rem 4rem;

  /* A fixed dark ink, not the offering's text colour.
     --op-text is whatever reads against the offer page's own background, which on a
     dark theme is white - and this page has a white background. Inheriting it made
     every label invisible. The theme still applies to the offer page; it does not
     apply here. */
  color: #0F172A;
  background: #fff;
}

/* The theme variables reach this page through the style attribute, so anything that
   reads them has to be neutralised too rather than left to inherit. */
.op-subscribe h1,
.op-subscribe h3,
.op-subscribe label,
.op-subscribe span,
.op-subscribe p,
.op-subscribe dt,
.op-subscribe dd,
.op-subscribe li { color: inherit; }
.op-subscribe__back {
  display: inline-block;
  margin-bottom: 1.5rem;
  font-size: .88rem;
  color: #64748B;
  text-decoration: none;
}
.op-subscribe__back:hover { color: #0F172A; }
.op-subscribe__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 3rem;
  margin-top: 1.5rem;
  align-items: start;
}
.op-subscribe__label {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  margin: 1.5rem 0 .4rem;
  color: #0F172A;
}
.op-subscribe__optional { font-weight: 400; color: #64748B; font-size: .8rem; }
.op-subscribe__amount { width: 100%; font-size: 1.35rem; }
.op-subscribe__source { width: 100%; }
.op-subscribe__hint {
  font-size: .82rem;
  color: #64748B;
  margin: .4rem 0 0;
}
.op-subscribe__check {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  margin: 1.75rem 0 1.25rem;
  font-size: .9rem;
  line-height: 1.5;
  cursor: pointer;
}
/* The checkbox keeps its size; the text takes the rest. Without this the span can be
   squeezed to nothing in a flex row. */
.op-subscribe__check > :first-child { flex: 0 0 auto; margin-top: .1rem; }
.op-subscribe__check > span { flex: 1 1 auto; }
.op-subscribe__submit { width: 100%; padding: .9rem; font-size: 1rem; }
.op-subscribe__note { font-size: .82rem; color: #64748B; margin-top: 1rem; line-height: 1.6; }
.op-subscribe__summary {
  background: color-mix(in srgb, currentColor 5%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
  border-radius: var(--op-radius, 8px);
  padding: 1.5rem;
}
.op-subscribe__summary h3 { margin: 0 0 1rem; font-size: 1.05rem; }
.op-subscribe__summary dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .5rem 1rem;
  margin: 0;
  font-size: .88rem;
}
.op-subscribe__summary dt { color: #64748B; }
.op-subscribe__summary dd { margin: 0; text-align: right; font-weight: 500; }
.op-subscribe__next ol { line-height: 1.9; padding-left: 1.2rem; }
.op-subscribe__next li { margin-bottom: .5rem; }

@media (max-width: 900px) {
  .op-subscribe__grid { grid-template-columns: 1fr; gap: 2rem; }
}

/* audit log */
.op-auditfilter {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: .75rem 0 1rem;
  flex-wrap: wrap;
}
.op-audit--sig { color: #B45309; }

/* ===========================================================================
   RESPONSIVE LAYER

   Added after everything else so these rules win without !important.

   Three widths rather than one: a laptop at 1280 is not a tablet at 900 and not a
   phone at 390, and collapsing straight from three columns to one skips the size
   where two still work. The public offer page already had its own rules at 900px;
   what follows fills in the admin screens, which had none - an issuer checking a
   raise from a phone was reading a desktop grid squeezed into 390 pixels.
   =========================================================================== */

/* ---- laptop and small desktop: 1280 and below ---- */
@media (max-width: 1280px) {

  /* The admin shell loses its generous gutters before it loses any structure. */
  .op-page, .op-admin-body { padding: 1.5rem 1.25rem; }

  /* Content editor: the block list narrows before it stacks. Losing the list
     entirely is worse than a narrow one - it is how an author keeps their place. */
  .op-contenteditor { grid-template-columns: 260px minmax(0, 1fr); gap: 1.25rem; }

  /* Integration settings: the description column is the one that can give way. */
  .op-setting { grid-template-columns: 220px minmax(0, 1fr) 130px 70px; gap: .75rem; }
}

/* ---- tablet and large phone: 900 and below ---- */
@media (max-width: 900px) {

  .op-page, .op-admin-body { padding: 1.25rem 1rem; }

  /* Admin header: title above actions, and the actions wrap rather than overflow. */
  .op-adminhead {
    flex-direction: column;
    align-items: flex-start;
    gap: .75rem;
  }
  .op-adminhead > div:last-child {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    width: 100%;
  }

  /* Content editor stacks, list first: choosing a block has to come before editing it. */
  .op-contenteditor { grid-template-columns: 1fr; }
  .op-contenteditor__list { max-height: 320px; overflow-y: auto; }

  /* Settings cards go single column. */
  .op-settings { grid-template-columns: 1fr; }

  /* Integration settings: label above the value, controls beneath. A four-column
     grid at this width gives every column too little to be readable. */
  .op-setting {
    grid-template-columns: 1fr;
    gap: .4rem;
    padding: 1rem 0;
  }

  /* Block editor field pairs stack. */
  .op-blockeditor__grid { grid-template-columns: 1fr; }

  /* Theme swatches: colour and hex on one line, description below. */
  .op-swatch { flex-wrap: wrap; }
  .op-swatch > div:not([class]) { flex-basis: 100%; }

  /* Data room and team rows keep their controls reachable rather than off-screen. */
  .op-dataroom__row { flex-wrap: wrap; }
  .op-dataroom__file { flex-basis: 100%; order: -1; }

  .op-teamedit__head { flex-wrap: wrap; }
  .op-teamedit__photoactions { flex-basis: 100%; }

  /* Subscribe page: summary below the form, not beside it. */
  .op-subscribe { padding: 1.5rem 1rem 3rem; }
  .op-subscribe__grid { grid-template-columns: 1fr; gap: 1.5rem; }

  /* Radzen grids do not reflow, so they scroll rather than overflow the page.
     A table clipped at the viewport edge looks like missing data; one that scrolls
     looks like a table. */
  .rz-datatable, .rz-data-grid { overflow-x: auto; }
  .rz-datatable table, .rz-data-grid table { min-width: 640px; }
}

/* ---- phone: 640 and below ---- */
@media (max-width: 640px) {

  .op-page, .op-admin-body { padding: 1rem .85rem; }

  /* Headings scale down. At 2.9rem a pitch headline takes most of a phone screen
     before a word of the pitch is read. */
  .op-pitch__headline { font-size: calc(1.85rem * var(--op-heading-scale)); }
  .op-hero__headline { font-size: calc(1.9rem * var(--op-heading-scale)); }
  .op-herobar__name { font-size: 1.05rem; }

  .op-pitch { padding: 2rem 1rem 1.5rem; }

  /* The pitch row: button full width, facts side by side beneath it.
     The facts are siblings of the button rather than a group of their own, so the
     wrapping is done here with flex-basis instead of on a container that does not
     exist. */
  .op-pitch__action { flex-wrap: wrap; gap: 1rem 1.25rem; }
  .op-pitch__cta { flex: 1 1 100%; width: 100%; }
  .op-pitch__fact { flex: 1 1 auto; }

  /* Hero: shorter, since 42vh of a phone screen is most of it. */
  .op-hero { min-height: 260px; max-height: 55vh; }
  .op-hero__inner { padding: 2rem 1rem; }

  /* Tabs scroll horizontally rather than wrapping into an unreadable stack. */
  .op-tabs {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .op-tabs::-webkit-scrollbar { display: none; }
  .op-tab { flex: 0 0 auto; }

  /* Invest panel and metrics. */
  .op-investpanel { padding: 1.25rem; }
  .op-metrics { grid-template-columns: 1fr 1fr; gap: 1.25rem; }

  /* Team and gallery: two across is still legible at this width; one is wasteful. */
  .op-team, .op-gallery--grid { grid-template-columns: 1fr 1fr; gap: 1.25rem; }
  .op-team__photo { width: 100%; max-width: 120px; }

  /* Admin header buttons go full width, so they are tappable rather than tiny. */
  .op-adminhead > div:last-child .rz-button { flex: 1 1 auto; }

  /* Sign-in artwork is already hidden below 900; tighten what remains. */
  .op-auth__form { padding: 1.5rem 1rem; }

  /* Audit filters stack. */
  .op-auditfilter { flex-direction: column; align-items: stretch; }

  /* Preview bar: status and exits on separate lines. */
  .op-previewbar { flex-direction: column; gap: .35rem; text-align: center; }
  .op-previewbar__actions { justify-content: center; }
}

/* ---- very small: 380 and below ---- */
@media (max-width: 380px) {
  /* Below this, two columns stop being two columns and become two slivers. */
  .op-metrics, .op-team, .op-gallery--grid { grid-template-columns: 1fr; }
  /* One fact per line: two of them in 380 pixels leaves neither readable. */
  .op-pitch__fact { flex: 1 1 100%; border-left: 0; padding-left: 0; }
}

/* ---- touch input, independent of width ---- */
@media (hover: none) and (pointer: coarse) {
  /* Sticky positioning fights momentum scrolling on iOS, and a rail that jitters is
     worse than one that scrolls with the page. */
  .op-body__rail, .op-tabs { position: static; }

  /* Targets large enough to hit without aiming. */
  .rz-button, .op-btn, .op-uploadbtn { min-height: 44px; }
}

/* signing documents */
.op-signdocs { display: grid; gap: 1rem; margin-top: 1rem; }
.op-signdocs__card { padding: 1.25rem; }
.op-signdocs__actions {
  display: flex;
  gap: .5rem;
  align-items: center;
  margin-top: 1rem;
  flex-wrap: wrap;
}

/* signing template preview */
.op-templatepreview {
  margin-top: 1.25rem;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  overflow: hidden;
  background: #F8FAFC;
}

/* investor subscription status */
.op-substatus {
  max-width: 780px;
  margin: 0 auto;
  padding: 2.5rem 2rem 4rem;

  /* Explicit, for the same reason as the subscribe page. This one sets no theme
     variables of its own, but it is reached from an offer page and inherits whatever
     that page left on the cascade - which on a dark theme is white text. */
  color: #0F172A;
  background: #fff;
}
.op-substatus__back {
  display: inline-block;
  margin-bottom: 1.25rem;
  font-size: .88rem;
  color: #64748B;
  text-decoration: none;
}
.op-substatus__amount { color: #64748B; margin-top: -.5rem; margin-bottom: 2rem; }
.op-substatus__note { font-size: .85rem; color: #64748B; line-height: 1.6; }

.op-steps { display: grid; gap: 0; margin: 1.5rem 0 2rem; }
.op-step {
  display: flex;
  gap: 1rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid #F1F5F9;
  opacity: .55;
}
.op-step:last-child { border-bottom: 0; }
.op-step.is-done, .op-step.is-current, .op-step.is-blocked { opacity: 1; }

.op-step__marker {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: #E2E8F0;
  color: #475569;
  display: flex; align-items: center; justify-content: center;
  font-size: .82rem; font-weight: 700;
}
.op-step.is-done .op-step__marker { background: #16A34A; color: #fff; }
.op-step.is-current .op-step__marker { background: #2563EB; color: #fff; }
.op-step.is-blocked .op-step__marker { background: #DC2626; color: #fff; }

.op-step__body { flex: 1 1 auto; min-width: 0; }
.op-step__title { font-weight: 600; margin-bottom: .2rem; }
.op-step__text { font-size: .88rem; color: #475569; line-height: 1.6; }
.op-step__action { margin-top: .75rem; }
.op-step__blocked {
  margin-top: .5rem; padding: .6rem .8rem;
  background: #FEF2F2; border-radius: 6px;
  font-size: .85rem; color: #991B1B;
}

.op-substatus__wire {
  border: 1px solid #E2E8F0; border-radius: 10px;
  padding: 1.5rem; margin-bottom: 1.5rem;
}
.op-substatus__wire dl {
  display: grid; grid-template-columns: auto 1fr;
  gap: .5rem 1.5rem; font-size: .9rem; margin: 0 0 1rem;
}
.op-substatus__wire dt { color: #64748B; }
.op-substatus__wire dd { margin: 0; font-family: ui-monospace, monospace; }

.op-substatus__docs { margin-top: 1.5rem; }
.op-substatus__doc {
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem .9rem; margin-bottom: .5rem;
  border: 1px solid #E2E8F0; border-radius: 8px;
  text-decoration: none; color: inherit; font-size: .9rem;
}
.op-substatus__doc:hover { background: #F8FAFC; }

.op-signframe { width: 100%; height: 780px; border: 1px solid #E2E8F0; border-radius: 8px; }

@media (max-width: 640px) {
  .op-substatus { padding: 1.5rem 1rem 3rem; }
  .op-signframe { height: 600px; }
}

/* an investor's own subscriptions, on the deals page */
.op-mysubs { display: grid; gap: .5rem; margin-bottom: 2.5rem; }
.op-mysubs__row {
  display: flex; align-items: center; gap: 1rem;
  padding: 1rem 1.25rem;
  border: 1px solid #E2E8F0; border-radius: 10px;
  text-decoration: none; color: inherit;
}
.op-mysubs__row:hover { background: #F8FAFC; border-color: #CBD5E1; }
.op-mysubs__name { flex: 1 1 auto; min-width: 0; }
.op-mysubs__ref {
  display: block; font-size: .78rem; color: #94A3B8;
  font-family: ui-monospace, monospace; margin-top: .15rem;
}
.op-mysubs__amount { font-weight: 600; flex: 0 0 auto; }
.op-mysubs__status { flex: 0 0 auto; text-align: right; }
.op-mysubs__badge {
  display: inline-block; padding: .2rem .6rem; border-radius: 999px;
  font-size: .75rem; font-weight: 600;
}
.op-mysubs__badge.is-progress { background: #DBEAFE; color: #1E40AF; }
.op-mysubs__badge.is-done { background: #DCFCE7; color: #166534; }
.op-mysubs__badge.is-problem { background: #FEE2E2; color: #991B1B; }
.op-mysubs__action {
  display: block; font-size: .74rem; color: #B45309;
  font-weight: 600; margin-top: .25rem;
}
.op-mysubs__heading { margin-top: 2rem; font-size: 1.15rem; }

@media (max-width: 640px) {
  .op-mysubs__row { flex-wrap: wrap; }
  .op-mysubs__name { flex-basis: 100%; }
}
.op-subscribe__country { width: 100%; }

/* theme preview: the pitch facts, so the emphasis border has something to show */
.op-themepreview__facts {
  display: flex;
  gap: 1rem;
  margin-top: 1rem;
  font-size: .78rem;
  color: var(--op-muted);
}
.op-themepreview__fact {
  padding-left: 1rem;
  border-left: 1px solid var(--op-border-accent, var(--op-border));
}
.op-settings__sub {
  margin: 1.75rem 0 .5rem;
  font-size: .95rem;
  padding-top: 1.25rem;
  border-top: 1px solid #E2E8F0;
}


/* identity verification page */
.op-verify { max-width: 640px; margin: 0 auto; padding: 2.5rem 2rem 4rem; color: #0F172A; background: #fff; }
.op-verify__back { display: inline-block; margin-bottom: 1.25rem; font-size: .88rem; color: #64748B; text-decoration: none; }
.op-verify__intro { line-height: 1.7; margin-bottom: 2rem; }
.op-verify__note { font-size: .85rem; color: #64748B; margin-top: 2rem; line-height: 1.6; }
.op-verify__failed { padding: 1rem; background: #FEF2F2; border-radius: 8px; color: #991B1B; font-size: .9rem; }
/* Embed flow only. Empty and collapsed in the other modes - :empty keeps it out of the
   layout until their iframe is actually injected, so a redirect or overlay page does not
   carry a blank gap where nothing will ever render. min-height rather than height: their
   content sets its own, and the point of embed is that we are not the ones capping it. */
.op-verify__embed { margin-top: 1.5rem; min-height: 620px; border-radius: 8px; overflow: hidden; }
.op-verify__embed:empty { min-height: 0; margin-top: 0; }
.op-verify__embed iframe { width: 100%; min-height: 620px; border: 0; display: block; }
.op-verify__start { margin-top: .5rem; }

/* ---------------------------------------------------------------------------
   TEMPORARY TEST HARNESS - remove with the panel in SubscriptionStatusPage.razor.
   Loud on purpose. This control fabricates a Rule 506(c) verification; it should
   never read as part of the investor's flow.
   --------------------------------------------------------------------------- */
.op-testbypass {
    margin-top: 2.5rem;
    padding: 1.25rem 1.5rem;
    border: 2px dashed #b45309;
    border-radius: 8px;
    background: repeating-linear-gradient(45deg, #fffbeb, #fffbeb 12px, #fef3c7 12px, #fef3c7 24px);
}
.op-testbypass__label {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #b45309;
    margin-bottom: .5rem;
}
.op-testbypass p { margin: 0 0 1rem; font-size: .9rem; color: #78350f; max-width: 60ch; }


/* ── large-investment meeting offer ─────────────────────────────────────────── */

.op-investpanel__meeting {
    margin-top: 1rem;
    padding: .875rem;
    border-radius: 8px;
    background: rgba(255, 255, 255, .12);
}

.op-investpanel__meetingtitle { font-weight: 600; margin-bottom: .35rem; }

.op-investpanel__meetingbody {
    font-size: .875rem;
    opacity: .9;
    margin: 0 0 .75rem;
}

.op-investpanel__meetingcta {
    width: 100%;
    padding: .6rem;
    border: 1px solid currentColor;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    font-weight: 600;
    cursor: pointer;
}

.op-investpanel__meetingcta:hover { background: rgba(255, 255, 255, .12); }

/* ── scheduler dialog ───────────────────────────────────────────────────────── */

.op-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(0, 0, 0, .6);
}

.op-modal__panel {
    position: relative;
    width: min(900px, 100%);
    height: min(720px, 90vh);
    background: #fff;
    border-radius: 10px;
    overflow: hidden;
}

.op-modal__frame { width: 100%; height: 100%; border: 0; }

.op-modal__close {
    position: absolute;
    top: .5rem;
    right: .75rem;
    z-index: 1;
    border: 0;
    background: transparent;
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
}

@media (max-width: 640px) {
    .op-modal { padding: 0; }
    .op-modal__panel { height: 100vh; border-radius: 0; }
}


/* ===========================================================================
   AUTHOR CONTENT: OVERFLOW CONTAINMENT

   Everything below constrains HTML this stylesheet did not write. Rich text and
   pitch bodies are pasted in through the block editor, so they arrive with
   whatever width the author's source had - an image exported at 1600px, a table
   from a spreadsheet, an email address with no break opportunity in it.

   One over-wide element does not overflow alone. It widens the document, and
   every paragraph on the page is then laid out to that width and clipped at the
   viewport edge - which reads as "the text is cut off" rather than "an image is
   too big", and sends you looking in the wrong place.
   =========================================================================== */

.op-richtext,
.op-pitch__body,
.op-section {
  /* Grid and flex children default to min-width:auto, which refuses to shrink
     below their content. Without this the track ignores every rule that follows. */
  min-width: 0;
}

.op-richtext img,
.op-richtext video,
.op-richtext iframe,
.op-richtext embed,
.op-richtext object,
.op-pitch__body img,
.op-pitch__body video,
.op-pitch__body iframe,
.op-pitch__body embed,
.op-pitch__body object {
  max-width: 100%;
  height: auto;
}

/* A width or height attribute on the element beats a stylesheet rule on height,
   so images pasted with dimensions still need the aspect ratio released. */
.op-richtext img[width],
.op-pitch__body img[width] { height: auto; }

/* Tables scroll inside their own box rather than widening the page. */
.op-richtext table,
.op-pitch__body table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
}

/* Preformatted text is the other common paste that carries its own width. */
.op-richtext pre,
.op-pitch__body pre {
  max-width: 100%;
  overflow-x: auto;
  white-space: pre-wrap;
}

/* An email address or long URL is a single unbreakable token. anywhere lets it
   break mid-string on a narrow screen; break-word would not. */
.op-richtext,
.op-pitch__body { overflow-wrap: anywhere; }

.op-richtext a,
.op-pitch__body a { word-break: break-word; }

@media (max-width: 640px) {

  /* Multi-column author text is unreadable at phone width - a column becomes a
     few words wide. Collapse regardless of what the block was configured with;
     the inline column-count is on the element, so this needs the extra weight. */
  .op-richtext[style] { column-count: 1 !important; }

  /* Blockquote indent costs a fifth of the line on a 390px screen. */
  .op-richtext blockquote,
  .op-pitch__body blockquote {
    margin-left: 0;
    margin-right: 0;
    padding-left: .9rem;
  }
}

/* Backstop. The rules above address the causes; this stops any one that was
   missed from taking the whole page sideways. clip rather than hidden - hidden
   on a page-level container silently kills position:sticky on the tab bar. */
.op-page,
.op-body,
.op-tabpanel { overflow-x: clip; }


/* ===========================================================================
   INVEST PANEL AND RAIL: OVERFLOW CONTAINMENT

   The panel is a grid child of .op-body, so it inherits the same min-width:auto
   default as the content column and stretches to whatever width the document has
   been forced to rather than to the viewport. That is why it can end up wider
   than the content behind it - the rail is not overflowing on its own, it is
   sizing to an already over-wide page.
   =========================================================================== */

.op-body__rail,
.op-investpanel,
.op-stickybar {
  min-width: 0;
  max-width: 100%;
}

/* The total row is label against value with the value pushed right. On a narrow
   screen a long label and a seven-figure amount cannot share a line, and the
   value carries white-space:nowrap - so it is the label that has to give. */
.op-investpanel__total { flex-wrap: wrap; }
.op-investpanel__totallabel { min-width: 0; }

/* A share count long enough to matter should not widen the field that holds it. */
.op-investpanel__input {
  max-width: 100%;
  box-sizing: border-box;
}

.op-investpanel__meeting,
.op-investpanel__meetingcta,
.op-investpanel__cta {
  max-width: 100%;
  box-sizing: border-box;
}

@media (max-width: 640px) {

  /* Below this the two halves of the total read better stacked than squeezed. */
  .op-investpanel__total {
    display: block;
  }
  .op-investpanel__totalvalue {
    display: block;
    margin-top: .25rem;
    font-size: 1.5rem;
  }
}


/* ===========================================================================
   FEATURE VIDEO ON A PHONE

   The 720px cap and the 1.5rem gutters are a desktop judgement - a video blown
   to the full content column reads as a banner, and the margins give the eye
   somewhere to rest. Neither holds at 390px, where the same gutters are an
   eighth of the screen and the cap is never reached anyway.
   =========================================================================== */

@media (max-width: 640px) {

  .op-video--feature {
    /* The per-block width is set inline as --op-video-width and would otherwise
       still apply. Nothing is cropped by ignoring it here: a 16:9 frame at full
       width is 219px tall on a 390px screen, which is small enough already. */
    max-width: 100%;
    padding: 1.5rem .5rem 1.25rem;
  }

  /* The pitch and rail versions already run full width; this keeps their
     vertical rhythm from doubling up against the section above. */
  .op-pitch__media .op-video--feature,
  .op-body__railmedia .op-video--feature { padding: .5rem 0 0; }
}

@media (max-width: 380px) {
  .op-video--feature { padding: 1.25rem .25rem 1rem; }
}


/* ===========================================================================
   HERO BANNER ON A PHONE

   cover fills the box and lets the overflow fall outside it. That is right for a
   photograph, where losing the edges costs nothing, and wrong for a banner, where
   the edges are the wordmark - a 390x260 box against a very wide image crops to
   the middle third and the brand name arrives as its last six letters.

   contain fits the whole image instead and pads the remainder. The padding is the
   hero's own background colour, so it reads as a band rather than as a gap.
   =========================================================================== */

@media (max-width: 640px) {

  .op-hero,
  .op-hero__bg {
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
  }

  /* The motion scales between 1.06 and 1.20 so no edge is ever exposed mid-cycle -
     which is precisely what contain needs to expose. Left running, the zoom crops
     back the width that contain just recovered. */
  .op-hero__bg--zoom,
  .op-hero__bg--pan,
  .op-hero__bg--drift {
    animation: none;
    transform: none;
  }

  /* Shorter than the 260px above, because a contained wide banner is short and the
     difference would otherwise be empty band above and below it. */
  .op-hero { min-height: 200px; max-height: none; }
}


/* The third hero layer. When a background video is set the image is carried as the
   video's poster, not as a background - so it is object-fit that crops it and
   background-size never applies. Same reasoning as the layer above: a banner loses
   its wordmark to a crop, where a photograph would lose nothing. */
@media (max-width: 640px) {
  .op-hero__video { object-fit: contain; }
}
