/* ═══════════════════════════════════════════════════════════════════════════
   O1 Tools — app chrome

   Consumes tokens.css from the marketing site unchanged, so the two stay in
   step without either importing the other's components. Only what the app
   needs and the site does not lives here: the two-column shell, the sign-in
   card, and the panels.
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-block-size: 100svh;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; }

.skip {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--green);
  color: var(--cream);
  transform: translateY(-120%);
  z-index: 100;
}
.skip:focus-visible { transform: none; }

.sr-only {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ───────────────────────────────────────────────────────── boot + centred */

.boot,
.centre {
  min-block-size: 100svh;
  display: grid;
  place-items: center;
  gap: var(--space-3);
  padding: var(--gutter);
  text-align: center;
}
.boot img { block-size: 2.1rem; inline-size: auto; }
.boot p { opacity: 0.6; margin: 0; }

/* ───────────────────────────────────────────────────────────── card */
/* Sign in, change password, and the no-team notice all wear the same card, so
   the three moments before you are "in" read as one sequence. */

.card {
  inline-size: min(100%, 26rem);
  background: var(--surface, #fff);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  text-align: start;
}
.card-mark { display: block; block-size: 2.1rem; inline-size: auto; margin-block-end: var(--space-4); }
.card h1 { font-size: var(--text-xl); margin: 0 0 var(--space-2); letter-spacing: -0.01em; }
.card p.lede { margin: 0 0 var(--space-4); opacity: 0.7; }

.field { display: block; margin-block-end: var(--space-3); }
.field span { display: block; font-size: var(--text-sm); margin-block-end: 0.35rem; opacity: 0.8; }
.field input {
  inline-size: 100%;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.field input:focus-visible { border-color: var(--focus-ring); }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.5rem;
  padding: 0.9rem 1.8rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--green);
  color: var(--cream);
  font-weight: 700;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) ease;
}
.btn:hover:not(:disabled) { transform: translateY(-2px); }
.btn:disabled { opacity: 0.55; cursor: default; }
.btn-full { inline-size: 100%; }
.btn-quiet { background: none; color: inherit; border: 1px solid var(--line); }

/* Errors are announced, not just coloured: a message that only differs by hue
   is invisible to a screen reader and to anyone who cannot separate red. */
.note {
  margin-block: var(--space-3) 0;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  border: 1px solid var(--line);
}
.note-bad { border-color: #b3261e; color: #b3261e; }
.note-good { border-color: var(--green); }

/* ───────────────────────────────────────────────────────────── shell */

.shell {
  display: grid;
  grid-template-columns: 17rem minmax(0, 1fr);
  min-block-size: 100svh;
}

.side {
  border-inline-end: 1px solid var(--line);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.side-mark { block-size: 2.1rem; inline-size: auto; align-self: start; }

.side-nav { display: flex; flex-direction: column; gap: 2px; list-style: none; margin: 0; padding: 0; }
.side-nav a {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: var(--text-sm);
}
.side-nav a:hover { background: rgb(2 28 21 / 0.05); }
.side-nav a[aria-current="page"] { background: rgb(2 28 21 / 0.08); font-weight: 700; }

.side-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.5;
  margin-block-end: 0.4rem;
}

/* An expired tool stays in the list and says so, rather than vanishing. A tool
   that disappears reads as a bug; one marked "view only" reads as a decision. */
.tag {
  margin-inline-start: auto;
  font-size: var(--text-xs);
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  opacity: 0.7;
}

.side-foot { margin-block-start: auto; font-size: var(--text-sm); }
.team-switch {
  inline-size: 100%;
  text-align: start;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
}
.team-switch small { display: block; opacity: 0.6; font-size: var(--text-xs); }
.by { margin-block-start: var(--space-3); font-size: var(--text-xs); opacity: 0.45; }

.main { padding: var(--space-5) var(--space-5) var(--space-7); min-inline-size: 0; }
.main h1 { font-size: var(--text-2xl); margin: 0 0 var(--space-2); letter-spacing: -0.02em; }

/* A banner, not a modal: someone on view-only still needs to reach their work
   and export it, so it must never block the screen. */
.banner {
  margin-block-end: var(--space-4);
  padding: 0.8rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  background: rgb(2 28 21 / 0.04);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--space-3);
  margin-block-start: var(--space-4);
}
.tile {
  display: block;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  text-decoration: none;
  background: var(--surface, #fff);
}
.tile:hover { border-color: var(--green); }
.tile h3 { margin: 0 0 0.25rem; font-size: var(--text-base); }
.tile time, .tile small { opacity: 0.6; font-size: var(--text-sm); }

table.rows { inline-size: 100%; border-collapse: collapse; margin-block-start: var(--space-4); }
table.rows th, table.rows td {
  text-align: start; padding: 0.7rem 0.6rem;
  border-block-end: 1px solid var(--line); font-size: var(--text-sm);
}
table.rows th { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.55; }

/* ───────────────────────────────────────────────────────── empty state */
/* The welcome canvas, borrowed from the marketing site's sketch gate. */

.welcome { text-align: center; padding-block: var(--space-6); }
.welcome canvas {
  inline-size: 100%;
  max-inline-size: 40rem;
  aspect-ratio: 3 / 2;
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  touch-action: none;
  cursor: crosshair;
  display: block;
  margin: var(--space-4) auto 0;
}

/* ───────────────────────────────────────────────────────── responsive */

@media (max-width: 48rem) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .side {
    border-inline-end: 0;
    border-block-end: 1px solid var(--line);
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
  }
  .side-nav { flex-direction: row; flex-wrap: wrap; inline-size: 100%; }
  .side-label { display: none; }
  .side-foot { margin: 0; inline-size: 100%; }
  .main { padding: var(--space-4) var(--gutter) var(--space-6); }
}

/* Compact action button for table rows. */
.btn-sm { padding: 0.35rem 0.8rem; font-size: var(--text-xs); }

/* The one-time password handover. It has to survive a glance, so it is
   selectable in one click and does not disappear on its own. */
.note-good p { margin: 0 0 0.4rem; }
.note-good p:last-child { margin: 0; opacity: 0.75; font-size: var(--text-xs); }

/* ───────────────────────────────────────────────── empty / dead-end card */

.card-empty { text-align: center; inline-size: min(100%, 28rem); }
.card-empty .card-mark { margin-inline: auto; }

/* The heading steps down rather than up. A dead end announced in display type
   reads as an error page; this is closer to a note. */
.card-empty .h-quiet {
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  margin-block: var(--space-3) var(--space-2);
}
.card-empty .lede { margin-inline: auto; max-inline-size: 32ch; text-wrap: pretty; }

/* The pencil line, in the same green as everything else but stepped well back:
   it is atmosphere, not information. */
.sketch-mark { margin-block-start: var(--space-4); color: var(--green); opacity: 0.28; }
.sketch-mark svg { inline-size: min(100%, 13rem); block-size: auto; display: block; margin-inline: auto; }

/* Buttons sat in a flex row with no wrapping rule, so "Email The O1 Space"
   broke across two lines inside its own pill. */
.card-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-block-start: var(--space-4);
}
.card-actions .btn { white-space: nowrap; }

@media (prefers-reduced-motion: no-preference) {
  .sketch-mark path {
    stroke-dasharray: 420;
    stroke-dashoffset: 420;
    animation: sketch-draw 1.6s var(--ease-out) forwards;
  }
  .sketch-mark path:last-child { animation-delay: 1.1s; }
  @keyframes sketch-draw { to { stroke-dashoffset: 0; } }
}
