/* Shell layout — the merged-page chrome. Widgets style themselves in their own
   shadow roots; this file only lays out header / platform nav / columns. */

/* The bar is a three-column grid with the platform switch in the middle, and the two
   outer columns are the SAME width. That is what centres the switch: `justify-content`
   cannot do it, because the brand and the account chip are different widths and any
   leftover space would go to one side. Equal tracks put the middle one exactly in the
   middle whatever is beside it.

   `minmax(0, 1fr)` rather than `1fr`, so a long display name in the account chip cannot
   push the middle column off centre -- a 1fr track has an automatic minimum, which means
   it refuses to shrink below its content and the centring quietly stops working on a
   narrow window. */
.shell__header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  height: var(--shell-header-h);
  padding: 0 var(--space-4);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* Brand and mark, grouped so they travel together and the grid's first cell shrinks
   from the right rather than pushing the wordmark apart from the logo. */
.shell__identity {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* The same file the loading screen and the sign-in gate already use, so the mark is
   literally the same artwork in all three places rather than three drawings of it. The
   natural size is 700x663; it is set at 28px square here, which keeps the wordmark's cap
   height as the dominant element and the mark as the identifier beside it. */
.shell__mark {
  width: 28px;
  height: 27px;
  flex: 0 0 auto;
  object-fit: contain;
  border-radius: 6px;
}

.shell__brand {
  font-size: 15px;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shell__nav {
  display: flex;
  gap: var(--space-1);
  justify-content: center;
  overflow-x: auto;
  scrollbar-width: none;
}
.shell__nav::-webkit-scrollbar { display: none; }

.platform-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-muted);
  font: inherit;
  font-size: 14px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  display: inline-flex;
  gap: var(--space-2);
  align-items: center;
  white-space: nowrap;
}

.platform-btn:hover { color: var(--color-text); background: var(--color-surface-2); }

.platform-btn.active {
  color: var(--color-bg);
  background: var(--color-accent);
  font-weight: 600;
}

/* ── the account chip ──────────────────────────────────────────────────────────
   One control instead of three. It used to be [Edit profile] [name] [Sign out] laid
   out as three loose siblings, which read as three unrelated things: the name was
   plain body text with no role, the two buttons were peers of it, and nothing about
   the group said "this is you and here is what you can do".

   Now it is a single pill carrying the person's own picture (or their initials, which
   is a real fallback rather than a grey circle), their name, and a caret. The actions
   live in a menu opened from it, so the bar holds one object instead of three, and the
   name is the label of the control rather than a decoration next to it. */
.shell__auth {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
}

.account {
  position: relative;
  min-width: 0;
}

.account__trigger {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--color-text);
  font: inherit;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.account__trigger:hover { background: var(--color-surface-2); }
.account__trigger:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.account__trigger[aria-expanded='true'] {
  background: var(--color-surface-2);
  border-color: var(--color-border);
}

/* The picture. A real avatar when the person has set one, and their initials when they
   have not -- taken from the display name, so two people called Alex do not get the
   same two letters for the same reason, and a name with no letters does not produce an
   empty circle. */
.account__avatar {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-accent);
  color: var(--snow-dark);
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
}
.account__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.account__name {
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.account__caret {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  fill: none;
  stroke: var(--color-muted);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s;
}
.account__trigger[aria-expanded='true'] .account__caret { transform: rotate(180deg); }

.account__menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  min-width: 208px;
  padding: var(--space-1);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Anchor-pointed: the menu is a child of the trigger's wrapper, which is only as wide
   as the pill, so it has to be told to hang from the wrapper's right edge rather than
   the header's. */
.account__menu[hidden] { display: none; }

.account__item {
  appearance: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: 13.5px;
  text-align: left;
  cursor: pointer;
}
.account__item:hover { background: var(--color-bg); }
.account__item:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.account__item .icon { width: 15px; height: 15px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.account__item--danger { color: var(--color-danger); }
.account__item--danger:hover { background: rgba(255, 138, 128, 0.12); }

.account__rule {
  height: 1px;
  margin: var(--space-1) 0;
  background: var(--color-border);
  border: 0;
}

/* Signed out: the chip has no person to show, so the bar keeps the grid and the middle
   column stays put rather than the whole layout shifting when a session ends. */
.shell__auth--empty { min-height: 36px; }

/* Below this the name is the first thing to go: the avatar and the caret still identify
   the control and still open the menu, so the bar loses a word rather than a target. */
@media (max-width: 640px) {
  .account__name { display: none; }
}

.shell__workspace {
  padding: var(--space-4);
  min-height: calc(100vh - var(--shell-header-h));
}

.shell__empty {
  color: var(--color-muted);
  padding: var(--space-5) 0;
  text-align: center;
}

.columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-4);
  align-items: start;
}

/* The Stoat app asks for calc(100vh - the header) and the workspace offers
   min-height calc(100vh - the header), so the two numbers agree -- except the
   workspace also has 16px of padding, and border-box puts that padding inside
   its height rather than around it. The app is therefore handed a box 32px
   shorter than the height it was promised, and the page ends up taller than the
   window: the app is inset on all four sides and its last 16px sit below the
   fold. The phone breakpoint below already drops this padding for the same
   reason; Stoat draws its own edges, so the shell adds none. */
.shell__workspace[data-platform="stoat"],
.shell__workspace[data-platform="pinterest"] {
  padding: 0;
  min-height: 0;
}

.columns[data-platform="stoat"],
.columns[data-platform="pinterest"] {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  height: calc(100vh - var(--shell-header-h));
}

.columns[data-platform="stoat"] > .column,
.columns[data-platform="pinterest"] > .column {
  min-width: 0;
  min-height: 0;
  height: 100%;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
}

.columns[data-platform="stoat"] .cell,
.columns[data-platform="pinterest"] .cell {
  height: 100%;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.columns[data-platform="stoat"] .cell > *,
.columns[data-platform="pinterest"] .cell > * {
  height: 100%;
  min-height: 0;
}

.columns[data-platform="stoat"] .cell__label,
.columns[data-platform="pinterest"] .cell__label {
  display: none;
}

/* ---- phone ---------------------------------------------------------------
   The shell is desktop chrome wrapped around a widget that is itself
   responsive, and without this the wrapper wins: the header row cannot shrink
   below the width of its contents, and .columns' 320px track floor plus the
   workspace padding makes the page wider than the phone, so the widget is laid
   out against a viewport it never sees. The widget's own phone breakpoint
   never fires and the mobile bar never appears. */
@media (max-width: 720px) {
  :root {
    --shell-header-h: 52px;
  }

  .shell__header {
    /* Allow the row to scroll rather than push the page wide. The brand and the
       sign-out button are the anchors; the platform nav is what scrolls. */
    gap: var(--space-2);
    padding: 0 var(--space-2) 0 var(--space-3);
    overflow: hidden;
  }

  .shell__brand {
    /* "Snow Community" is 15 characters and costs more width than it earns on
       a phone. The mark alone is enough to identify the app. */
    font-size: 0;
    white-space: nowrap;
  }
  .shell__brand::before {
    content: 'Snow';
    font-size: 15px;
  }

  .shell__nav {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .shell__nav::-webkit-scrollbar { display: none; }

  .platform-btn {
    padding: var(--space-1) var(--space-2);
    font-size: 13px;
  }
  .platform-btn .icon { display: none; }

  .shell__auth { flex: 0 0 auto; }
  .shell__auth span { display: none; }
  .shell__auth .ghost { padding: var(--space-1) var(--space-2); }

  .shell__workspace {
    /* No padding: the widget draws its own edges, and 16px of it on each side
       is 32px of a 390px screen. */
    padding: 0;
    min-height: 0;
  }

  .columns,
  .columns[data-platform="stoat"],
  .columns[data-platform="pinterest"] {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  /* dvh, not vh: on mobile the browser chrome collapses and scrolls, and a vh
     height is taller than the visible area, which pushes the composer below
     the fold and gives the page a scrollbar it should not have. */
  .columns[data-platform="stoat"],
  .columns[data-platform="pinterest"] {
    height: calc(100dvh - var(--shell-header-h));
  }

  .cell { border-radius: 0; }
}

.column { display: grid; gap: var(--space-4); }

.cell {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  min-height: 120px;
}

.cell__label { color: var(--color-muted); font-size: 12px; letter-spacing: 0.4px; text-transform: uppercase; margin-bottom: var(--space-2); }

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

.cell__error { color: var(--color-danger); font-size: 13px; }

.shell__toast {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  box-shadow: var(--shadow-2);
  font-size: 14px;
  z-index: 40;
}
/* ---- sign-in gate -------------------------------------------------------- */
/* The SNOW Campus Community sign-in screen: the same deep teal and the same
   single green accent as the loading screen it hands over to, so signing in is
   a change of content rather than a change of product.

   It used to be a light, blue-accented card on the theory that the workspace
   behind it was a light theme. The workspace is no longer light -- it is this
   palette too -- so that reasoning no longer applies, and a light sign-in
   screen in front of a dark app is the same split-product problem it was
   avoiding. */

body.is-gated {
  overflow: hidden;
}

/* The `hidden` attribute is only a UA-stylesheet hint, so any `display` rule on
   this class beats it and the gate stays painted over a signed-in workspace.
   Restating it here is the only thing that makes `hidden = true` mean hidden. */
.authgate[hidden] {
  display: none;
}

.authgate {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px;
  overflow-y: auto;
  /* The loading screen's own background, so the hand-off from one to the other
     is a cross-fade rather than a colour jump. */
  background:
    radial-gradient(circle at 50% 42%, rgba(11, 96, 124, .28), transparent 44%),
    linear-gradient(145deg, #031d2a 0%, #07384d 56%, #021b28 100%);
  color: #eaf4f7;
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  animation: authgate-in .22s ease-out;
}

@keyframes authgate-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* A very soft wash behind the card so it does not float on a flat field. */
.authgate__glow {
  position: absolute;
  width: 560px;
  height: 560px;
  max-width: 90vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(121, 214, 61, .12) 0%, rgba(121, 214, 61, 0) 66%);
  filter: blur(8px);
  pointer-events: none;
}

.authgate__card {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: 34px 34px 26px;
  border-radius: 18px;
  /* Lighter than the page behind it, so the card reads as raised rather than as
     a hole. On the light theme this was the other way round. */
  border: 1px solid #1d4f66;
  background: #07384d;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, .3),
    0 14px 38px rgba(0, 0, 0, .45);
}

/* The brand block stacks: the mark on top, the name beneath it.
   It was a row, which suited a 30px icon. The real artwork is 700x663 and
   carries a wordmark inside it, so it needs room to be legible, and a 30px
   square of it reads as a smudge. */
.authgate__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
  text-align: center;
}
/* Bounded by height rather than width: the image is 700x663, so this keeps the
   artwork's proportions exactly and cannot squash it. 120px tall is wide enough
   for the wordmark inside the mark to be readable. */
.authgate__mark {
  display: block;
  width: auto;
  height: 120px;
  max-width: 100%;
  object-fit: contain;
}
.authgate__brandname {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .01em;
  color: #a8c4d0;
}

.authgate__title {
  margin: 0 0 6px;
  font-size: 25px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.2;
  color: #eaf4f7;
}
.authgate__subtitle {
  margin: 0 0 22px;
  font-size: 14px;
  line-height: 1.55;
  color: #a8c4d0;
}

.authgate__form { display: flex; flex-direction: column; gap: 14px; }

.authgate__field { display: flex; flex-direction: column; gap: 6px; }
.authgate__label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .01em;
  color: #a8c4d0;
}

.authgate__input {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 14px;
  color: #eaf4f7;
  /* A shade above the card, so the field is visibly a control rather than a
     gap in the panel. */
  background: #0d3b52;
  border: 1px solid #24596f;
  border-radius: 9px;
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.authgate__input::placeholder { color: #6d93a3; }
.authgate__input:hover { border-color: #2f6d85; }
.authgate__input:focus {
  border-color: #79d63d;
  box-shadow: 0 0 0 3px rgba(121, 214, 61, .26);
}
.authgate__input[aria-invalid="true"] {
  border-color: #ff8a80;
}
.authgate__input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(255, 138, 128, .25);
}

.authgate__password { position: relative; display: flex; }
.authgate__password .authgate__input { padding-right: 62px; }
.authgate__reveal {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  padding: 5px 9px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: #a8c4d0;
  background: #0d3b52;
  border: 1px solid #1d4f66;
  border-radius: 6px;
  cursor: pointer;
}
.authgate__reveal:hover { background: #12455d; color: #eaf4f7; }
.authgate__reveal:focus-visible { outline: 2px solid #79d63d; outline-offset: 1px; }

.authgate__hint { margin: 0; font-size: 11.5px; color: #7fa3b2; }

/* Holds the error message. It is a real element because the message is added
   and removed as the person types, and re-rendering the form to do that would
   wipe the fields. It must not contribute a gap while it is empty. */
.authgate__banner-slot:empty {
  display: none;
}

.authgate__banner {
  margin: 0;
  padding: 9px 12px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.45;
  color: #ffb4ab;
  background: rgba(255, 138, 128, .12);
  border: 1px solid rgba(255, 138, 128, .34);
  border-radius: 8px;
}

.authgate__submit {
  margin-top: 4px;
  padding: 12px 16px;
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: .01em;
  color: #031d2a;
  background: #79d63d;
  border: 0;
  border-radius: 9px;
  cursor: pointer;
  transition: filter .15s ease, transform .06s ease;
}
.authgate__submit:hover:not(:disabled) { filter: brightness(1.08); }
.authgate__submit:active:not(:disabled) { transform: translateY(1px); }
.authgate__submit:disabled { opacity: .6; cursor: default; }
.authgate__submit:focus-visible { outline: 2px solid #eaf4f7; outline-offset: 2px; }

.authgate__switch {
  margin: 18px 0 0;
  font-size: 13px;
  color: #a8c4d0;
  text-align: center;
}
.authgate__link {
  padding: 2px 2px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: #79d63d;
  background: none;
  border: 0;
  cursor: pointer;
}
.authgate__link:hover { text-decoration: underline; }
.authgate__link:focus-visible { outline: 2px solid #79d63d; outline-offset: 1px; border-radius: 4px; }

.authgate__fineprint {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid #1d4f66;
  font-size: 11px;
  line-height: 1.5;
  color: #7fa3b2;
  text-align: center;
}

@media (max-width: 460px) {
  .authgate { padding: 16px; }
  .authgate__card { padding: 26px 22px 20px; border-radius: 16px; }
  .authgate__title { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .authgate { animation: none; }
  .authgate__input, .authgate__submit { transition: none; }
}
