/* portal.css — the portal's own chrome, and only that.
 *
 * app.css above this file IS the Ops Studio identity, ported byte for byte
 * from the mini app: black #0B0B0C, paper #F4F4F2, orange #FF5A1F as a
 * point and never a wash, mono small-caps for labels. Nothing here repaints
 * a card, a row, the sheet or the week strip — this file adds the three
 * things a browser tab needs that a Telegram webview did not:
 *
 *   1. a door        (.login)
 *   2. a plane row   (which studio, and the way out)
 *   3. a shell       (on a wide screen, the chat panel beside the column)
 *
 * Every colour below is one of app.css's tokens, so both schemes follow for
 * free — there is not one hex code in this file that is not the identity's
 * one fixed orange.
 */

/* ---- the door -------------------------------------------------------------
   One card, centred, on the app's own ground. It sizes from its content and
   from the viewport (dvh, so an iOS URL bar cannot crop the button off the
   bottom), and never scrolls sideways. */

.login {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6) var(--sp-4);
  min-height: 100vh;
  min-height: 100dvh;
}

.login-card {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-6) var(--sp-5) var(--sp-5);
}

/* The mark, at the size it is a mark and not a logo. */
.login-sigil { width: 34px; height: 34px; margin: 0 0 var(--sp-3h); }

.login-title {
  font-family: var(--font-heading);
  font-size: 23px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.login-sub {
  margin: var(--sp-1h) 0 var(--sp-5);
  font-size: 14px;
  color: var(--hint);
}

/* The label voice: the identity's small mono caps, same register as the
   scheme pill and the stat captions. */
.login-lab {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hint);
  margin-bottom: var(--sp-1h);
}

.login-in {
  font: inherit;
  font-size: 16px;               /* 16px or iOS zooms the page on focus */
  width: 100%;
  box-sizing: border-box;
  padding: var(--sp-2h) var(--sp-3);
  margin-bottom: var(--sp-3h);
  color: var(--text);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  -webkit-appearance: none;
  appearance: none;
}
.login-in:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 1px; }

/* A failure is text, in the destructive tone that reads at 4.5:1 on every
   surface this card can sit on. Never colour alone: it says what happened. */
.login-err {
  margin: 0 0 var(--sp-3);
  font-size: 13px;
  line-height: 1.4;
  color: var(--destructive-text);
}

.login-go { max-width: none; margin-top: var(--sp-1); }

.login-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin: var(--sp-5) 0 0;
}

/* The wordmark, in the same small-caps label voice as the mini app's. */
.login-mark {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--hint);
}

/* ---- the plane row --------------------------------------------------------
   Which studio you are in, who you are, and out. Chrome, so it speaks the
   label voice and stays quiet: this row is never the reason anyone opens
   the app. */

.plane-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding-top: var(--sp-2h);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hint);
}

.plane-lab { flex: 0 0 auto; }

.plane-select {
  font: inherit;
  letter-spacing: 0.1em;
  color: var(--text);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 3px var(--sp-1h);
  max-width: 52vw;
}

/* The email is the least important thing in the header: it exists so a
   founder can tell WHICH account they are in, and it gets out of the way
   before it can push the sign-out button off a narrow screen. */
.plane-who {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-transform: none;
  letter-spacing: 0.02em;
  text-align: right;
}

.plane-out {
  flex: 0 0 auto;
  position: relative;
  font: inherit;
  color: var(--hint);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 3px var(--sp-2h);
  min-height: 22px;
}
/* The tap target the 22px pill does not have. */
.plane-out::before { content: ""; position: absolute; inset: -10px; }

/* ---- the shell ------------------------------------------------------------
   On a phone this is exactly the mini app: one 560px column, cards stacked.
   The wrapper below only re-creates the gap .main was providing before the
   chat panel needed a sibling. */

.studio-col {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3h);
  min-width: 0;
}

/* ---- chat ---------------------------------------------------------------- */

.chat-body { min-width: 0; }

.chat-empty { padding: var(--sp-3) 2px var(--sp-2); }
.chat-empty .big { font-size: 15px; color: var(--text); margin-bottom: 3px; }
.chat-empty .dim { font-size: 13px; color: var(--hint); line-height: 1.5; }

.chat-list { display: flex; flex-direction: column; gap: var(--sp-3); }

.chat-msg { max-width: 90%; }
.chat-msg.mine { align-self: flex-end; }

.chat-who {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hint);
  margin-bottom: 3px;
}
.chat-at { text-transform: none; letter-spacing: 0.02em; }

.chat-text {
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;         /* a message keeps the breaks it was written with */
  overflow-wrap: anywhere;       /* a pasted URL never widens the page */
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-2h);
}
/* The founder's own side carries the point of accent — the one place in this
   file the orange appears, and as a 2px edge, never a fill. */
.chat-msg.mine .chat-text { border-left: 2px solid var(--accent); }

/* ---- wide screens ---------------------------------------------------------
   The studio column keeps its 560px measure — it is tuned for one thumb and
   it does not improve at 900px — and the space a desktop actually adds goes
   to the conversation, which is the thing that wants room. Below 1040px the
   chat is simply the last card. */

@media (min-width: 1040px) {
  .brandbar,
  .main { max-width: 1160px; }

  /* The three numbers describe the queue, so they stay over the queue's
     column. Spread across the full 1160 they read as three unrelated
     figures with a desk between them. */
  .brand-stats { max-width: 560px; }

  .main {
    display: grid;
    grid-template-columns: minmax(0, 560px) minmax(0, 1fr);
    align-items: start;
    gap: var(--sp-5);
    padding-left: var(--sp-4);
    padding-right: var(--sp-4);
  }

  /* The queue scrolls; the conversation stays put beside it. */
  .chat {
    position: sticky;
    top: var(--sp-4);
    display: flex;
    flex-direction: column;
    max-height: calc(100dvh - 2 * var(--sp-4));
  }
  .chat .chat-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }
}

/* ---- the sheet, on a screen it was never drawn for ------------------------
   Found in the first desktop screenshot of this build, and worth stating
   plainly because it is the kind of defect that ships: the mini app's sheet
   is a bottom sheet pinned left-to-right, which on a phone is a full plane
   and at 1280px is a 1264px-wide APPROVE button in solid orange. That is
   the identity's one rule broken (the orange is a point, never a wash), and
   it is a click target the width of the desk under the founder's cursor —
   on the one screen in this product where the wrong tap cannot be undone.

   So on a wide screen the panel becomes a centred column of the same
   measure as the studio itself. It stays a bottom sheet, it stays modal,
   and the scrim still covers everything: the fix is the panel's width, not
   its behaviour. */

@media (min-width: 720px) {
  .panel {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: min(640px, calc(100vw - 2 * var(--sp-6)));
    max-height: 88dvh;
    /* Off the floor, so it reads as a dialog rather than a docked drawer. */
    bottom: var(--sp-6);
    border-radius: var(--r-xl);
  }
  /* The rise must keep the centring, or the panel jumps to the left edge
     for the length of the animation. */
  @keyframes rise-centred {
    from { transform: translateX(-50%) translateY(24px); opacity: 0.6; }
    to { transform: translateX(-50%) translateY(0); opacity: 1; }
  }
  .panel { animation-name: rise-centred; }

  /* The action row is the point of the sheet, not the width of the room. */
  .panel-foot .btn { max-width: 340px; margin-left: auto; margin-right: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .panel { animation: none; }
}
