/* =========================================================================
   The Tutorial Assets panel
   -------------------------------------------------------------------------
   Same position on every page, always the same sections in the same order —
   Connect your flow, Your flow will receive, APIs your flow can call,
   Exceptions simulator rules, Activity — with the docs links pinned under them,
   and a section the page has nothing for is hidden rather than padded. The
   training teaches this as a convention from lesson one, so its placement and
   contents are a contract, not a layout preference.

   It looks nothing like the shop on purpose. The shop is the fiction; this is
   the workbench. Graphite, graph paper, monospace — a learner should never be
   in doubt about which layer they are looking at.
   ========================================================================= */

:root {
  --tp-ink:      #171c1a;
  --tp-panel:    #1e2522;
  --tp-raised:   #273029;
  --tp-line:     #37423b;
  --tp-text:     #d9e2da;
  --tp-dim:      #8c9a8f;
  --tp-accent:   #e0714d;
  --tp-good:     #6fbf8b;
  --tp-warn:     #d8a441;
  --tp-bad:      #e0614d;
  --tp-w:        clamp(320px, 30vw, 440px);
}

/* --- the closed tab ---------------------------------------------------- */

.ta-tab {
  position: fixed; z-index: 9000;
  right: 0; top: 50%; transform: translateY(-50%);
  background: var(--tp-panel); color: var(--tp-text);
  border: none; border-right: 0;
  border-top-left-radius: 4px; border-bottom-left-radius: 4px;
  padding: 1.1rem .55rem;
  font-family: var(--mono); font-size: .68rem;
  letter-spacing: .2em; text-transform: uppercase;
  writing-mode: vertical-rl;
  cursor: pointer;
  box-shadow: -2px 0 12px rgba(0, 0, 0, .22);
  transition: padding-right .18s, background .18s;
}
.ta-tab:hover { padding-right: .85rem; background: var(--tp-raised); }
.ta-tab:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 2px; }

/* An unread marker on Activity — the only thing that ever pulls at attention. */
.ta-tab[data-unread]:not([data-unread='0'])::after {
  content: attr(data-unread);
  display: block; margin-top: .55rem;
  background: var(--tp-accent); color: #fff;
  writing-mode: horizontal-tb;
  font-size: .6rem; line-height: 1; padding: .2rem .3rem; border-radius: 999px;
}

/* --- page reflow ------------------------------------------------------- */

/* The panel is docked, not floating, so opening it makes room rather than
   covering the page. This matters most on the Contact page: the panel opens
   itself when a URL is missing, and it must not hide the form the learner is
   in the middle of filling in. Below the breakpoint it overlays instead —
   there is no room to reflow into. */
@media (min-width: 900px) {
  body {
    transition: padding-right .28s cubic-bezier(.2, .7, .3, 1);
  }
  :root[data-ta-open='true'] body {
    padding-right: var(--tp-w);
  }
}
@media (prefers-reduced-motion: reduce) { body { transition: none; } }

/* --- the drawer -------------------------------------------------------- */

.ta {
  position: fixed; z-index: 9001;
  top: 0; right: 0; bottom: 0;
  width: var(--tp-w);
  display: flex; flex-direction: column;
  background: var(--tp-panel);
  color: var(--tp-text);
  font-family: var(--mono);
  font-size: .78rem;
  line-height: 1.5;
  box-shadow: -8px 0 32px rgba(0, 0, 0, .3);
  transform: translateX(100%);
  transition: transform .28s cubic-bezier(.2, .7, .3, 1);
}
.ta[data-open='true'] { transform: none; }
@media (prefers-reduced-motion: reduce) { .ta { transition: none; } }

/* Graph paper. Quiet, but it says "working surface" instantly. */
.ta::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(rgba(255,255,255,.032) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.032) 1px, transparent 1px);
  background-size: 22px 22px;
}

.ta__head {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: .6rem;
  padding: .85rem 1rem;
  border-bottom: 1px solid var(--tp-line);
  background: var(--tp-ink);
}
.ta__title { font-size: .7rem; letter-spacing: .2em; text-transform: uppercase; margin: 0; font-family: var(--mono); font-weight: 500; }
.ta__page { color: var(--tp-dim); font-size: .66rem; margin-left: auto; }
.ta__close {
  background: none; border: 1px solid var(--tp-line); color: var(--tp-text);
  width: 1.6rem; height: 1.6rem; line-height: 1; cursor: pointer; border-radius: 3px;
}
.ta__close:hover { border-color: var(--tp-accent); color: var(--tp-accent); }

.ta__scroll { position: relative; z-index: 1; overflow-y: auto; flex: 1; overscroll-behavior: contain; }

/* --- sections ---------------------------------------------------------- */

.ta-sec { border-bottom: 1px solid var(--tp-line); }
.ta-sec__btn {
  width: 100%; display: flex; align-items: center; gap: .6rem;
  background: none; border: 0; color: var(--tp-text);
  padding: .8rem 1rem; cursor: pointer; text-align: left;
  font-family: var(--mono); font-size: .68rem;
  letter-spacing: .18em; text-transform: uppercase;
}
.ta-sec__btn:hover { background: var(--tp-raised); }
.ta-sec__btn:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: -2px; }
.ta-sec__count { margin-left: auto; color: var(--tp-dim); font-size: .64rem; }
.ta-sec__chev { transition: transform .18s; color: var(--tp-dim); }
.ta-sec[data-open='true'] .ta-sec__chev { transform: rotate(90deg); }
.ta-sec__body { padding: 0 1rem 1.1rem; display: none; }
.ta-sec[data-open='true'] .ta-sec__body { display: block; }

/* --- 01 connect your flow ---------------------------------------------- */

.ta-field + .ta-field { margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px dashed var(--tp-line); }
.ta-field__label { display: block; color: var(--tp-text); margin-bottom: .2rem; }
.ta-field__hint { color: var(--tp-dim); font-size: .7rem; margin: 0 0 .5rem; line-height: 1.45; }
.ta-field__hint a { color: var(--tp-accent); }

.ta-input {
  width: 100%; background: var(--tp-ink); color: var(--tp-text);
  border: 1px solid var(--tp-line); border-radius: 3px;
  padding: .5rem .6rem; font-family: var(--mono); font-size: .74rem;
}
.ta-input:focus { outline: none; border-color: var(--tp-accent); }
.ta-input[aria-invalid='true'] { border-color: var(--tp-bad); }

.ta-field__row { display: flex; gap: .4rem; margin-top: .5rem; flex-wrap: wrap; }

.ta-btn {
  background: var(--tp-raised); color: var(--tp-text);
  border: 1px solid var(--tp-line); border-radius: 3px;
  padding: .38rem .7rem; cursor: pointer;
  font-family: var(--mono); font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase;
}
.ta-btn:hover:not(:disabled) { border-color: var(--tp-accent); color: var(--tp-accent); }
.ta-btn:disabled { opacity: .45; cursor: not-allowed; }
.ta-btn--primary { background: var(--tp-accent); border-color: var(--tp-accent); color: #14100e; font-weight: 600; }
.ta-btn--primary:hover:not(:disabled) { filter: brightness(1.12); color: #14100e; }

.ta-err { color: var(--tp-bad); font-size: .7rem; margin: .4rem 0 0; }

/* Status chip: Not connected / Connected / Last call: 200 OK, 340 ms */
.ta-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: .5rem; padding: .2rem .5rem; border-radius: 999px;
  font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid currentColor;
}
.ta-chip::before { content: ''; width: .42rem; height: .42rem; border-radius: 50%; background: currentColor; }
.ta-chip[data-state='empty']     { color: var(--tp-dim); }
.ta-chip[data-state='connected'] { color: var(--tp-good); }
.ta-chip[data-state='ok']        { color: var(--tp-good); }
.ta-chip[data-state='pending']   { color: var(--tp-warn); }
.ta-chip[data-state='error']     { color: var(--tp-bad); }

/* When an action needs a URL that isn't set, the panel opens itself and this
   fires. Never fail silently — say what's missing and where to put it. */
@keyframes ta-flag {
  0%, 100% { box-shadow: 0 0 0 0 rgba(224, 113, 77, 0); }
  30%      { box-shadow: 0 0 0 3px rgba(224, 113, 77, .55); }
}
.ta-field--wanted .ta-input { animation: ta-flag 1.1s ease-out 2; border-color: var(--tp-accent); }
.ta-field--wanted .ta-field__label { color: var(--tp-accent); }

/* --- 02 APIs on this page ---------------------------------------------- */

.ta-api { border: 1px solid var(--tp-line); border-radius: 3px; margin-bottom: .5rem; }
.ta-api__head { display: flex; align-items: center; gap: .5rem; padding: .45rem .55rem; }
.ta-api__method {
  font-size: .6rem; letter-spacing: .08em; padding: .12rem .35rem; border-radius: 2px;
  background: var(--tp-raised); color: var(--tp-good);
}
.ta-api__path { color: var(--tp-text); overflow-wrap: anywhere; flex: 1; font-size: .71rem; }
.ta-api__note { color: var(--tp-dim); font-size: .68rem; padding: 0 .55rem .5rem; margin: 0; line-height: 1.45; }

.ta-copy {
  background: none; border: 1px solid var(--tp-line); color: var(--tp-dim);
  border-radius: 2px; cursor: pointer; padding: .1rem .35rem;
  font-family: var(--mono); font-size: .58rem; letter-spacing: .08em; text-transform: uppercase;
  flex-shrink: 0;
}
.ta-copy:hover { color: var(--tp-accent); border-color: var(--tp-accent); }
.ta-copy[data-done='true'] { color: var(--tp-good); border-color: var(--tp-good); }

.ta-pre {
  background: var(--tp-ink); border: 1px solid var(--tp-line); border-radius: 3px;
  padding: .55rem; margin: 0;
  font-size: .68rem; line-height: 1.45; color: var(--tp-text);
  max-height: 15rem; overflow-y: auto;
  /* Wrap rather than scroll sideways: the long lines here are URLs and header
     values, and a learner comparing a payload against their trigger should not
     have to scroll a narrow drawer horizontally to read one. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* --- 04 activity ------------------------------------------------------- */

.ta-log { list-style: none; margin: 0; padding: 0; }
.ta-log__empty { color: var(--tp-dim); font-size: .7rem; line-height: 1.5; }

.ta-ex { border: 1px solid var(--tp-line); border-radius: 3px; margin-bottom: .4rem; background: var(--tp-ink); }
.ta-ex__btn {
  width: 100%; display: flex; align-items: center; gap: .45rem;
  background: none; border: 0; color: var(--tp-text); cursor: pointer;
  padding: .45rem .55rem; text-align: left; font-family: var(--mono); font-size: .68rem;
}
.ta-ex__btn:hover { background: var(--tp-raised); }
.ta-ex__status { font-weight: 600; flex-shrink: 0; }
.ta-ex__status[data-ok='true']  { color: var(--tp-good); }
.ta-ex__status[data-ok='false'] { color: var(--tp-bad); }
.ta-ex__url { color: var(--tp-dim); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ta-ex__ms { color: var(--tp-dim); font-size: .62rem; flex-shrink: 0; }
.ta-ex__body { display: none; padding: 0 .55rem .55rem; }
.ta-ex[data-open='true'] .ta-ex__body { display: block; }
.ta-ex__h { color: var(--tp-dim); font-size: .6rem; letter-spacing: .14em; text-transform: uppercase; margin: .6rem 0 .25rem; }
.ta-ex__actions { display: flex; gap: .35rem; margin-top: .55rem; }

.ta-trunc { color: var(--tp-warn); font-size: .64rem; margin-top: .3rem; }

/* --- responsive -------------------------------------------------------- */

@media (max-width: 640px) {
  :root { --tp-w: 100vw; }
  .ta-tab { top: auto; bottom: 0; right: 50%; transform: translateX(50%);
            writing-mode: horizontal-tb; border-radius: 4px 4px 0 0; padding: .55rem 1.1rem; }
  .ta-tab:hover { padding-right: 1.1rem; }
}

/* "Your flow will receive" — the payload Flowland POSTs to a trigger. Marked
   differently from an endpoint the learner calls, because the direction is the
   opposite one and confusing them is the whole reason this section exists. */
.ta-api__method--in { color: var(--tp-warn); }
.ta-api__initial { color: var(--tp-dim); font-style: italic; padding-top: .4rem; }

/* A page that serves no lesson. One clear statement beats four empty sections. */
.ta-idle { padding: 1.1rem 1rem; border-bottom: 1px solid var(--tp-line); }
.ta-idle p { margin: 0 0 .6rem; color: var(--tp-dim); font-size: .74rem; line-height: 1.55; }
.ta-idle p:last-child { margin-bottom: 0; }
.ta-idle strong { color: var(--tp-text); }

/* The log is kept in this browser, which is worth saying where the bodies are:
   they hold whatever was typed into a form. Hence the Clear button next to it. */
.ta-log__note {
  margin: 0 0 .6rem; font-size: .66rem; line-height: 1.5;
  color: var(--tp-dim);
}
.ta-log__clear {
  background: none; border: 0; padding: 0 0 0 .2rem; cursor: pointer;
  font-family: var(--mono); font-size: .66rem;
  color: var(--tp-accent); text-decoration: underline;
}
.ta-log__clear:hover { color: var(--tp-text); }
.ta-log__clear:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 2px; }

/* A row from a previous visit says so. A 405 from yesterday sitting in the list
   with a duration reads as though it had just happened. */
.ta-ex[data-earlier='true'] .ta-ex__ms { font-style: italic; opacity: .8; }

/* The row: the expand toggle, and Resend beside it. On the row rather than
   inside it, because a learner who has just changed something in their flow
   wants one click. */
.ta-ex__row { display: flex; align-items: stretch; }
.ta-ex__row .ta-ex__btn { flex: 1; min-width: 0; }

.ta-ex__again {
  flex: none;
  border: 0; border-left: 1px solid var(--tp-line);
  background: transparent; color: var(--tp-accent);
  font-family: var(--mono); font-size: .6rem;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 0 .6rem; cursor: pointer;
  transition: background .15s, color .15s;
}
.ta-ex__again:hover:not(:disabled) { background: var(--tp-accent); color: var(--tp-ink); }
.ta-ex__again:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: -2px; }
.ta-ex__again:disabled { opacity: .5; cursor: progress; }

/* What the flow answered, on the row of the request that made Flowland call it.
   A learner who has just pressed Send is waiting for this number, not for the
   200 that says Flowland accepted the form. */
.ta-ex__flow {
  flex-shrink: 0; font-size: .6rem; letter-spacing: .06em;
  padding: .05rem .3rem; border-radius: 2px;
  border: 1px solid currentColor;
}
.ta-ex__flow[data-ok='true']  { color: var(--tp-good); }
.ta-ex__flow[data-ok='false'] { color: var(--tp-bad); }

/* The leg itself, inside the row: what Flowland sent the flow and what came
   back, verbatim, for comparing against the trigger's Initial Data. */
.ta-ex__leg { margin-top: .6rem; padding-top: .2rem; border-top: 1px dashed var(--tp-line); }

/* A row that is Flowland calling the flow on its own — from the sandbox's clock,
   with no request from this page behind it — says why it has no Resend. */
.ta-ex__hint {
  margin: .5rem 0 0; font-size: .68rem; line-height: 1.45;
  color: var(--tp-dim);
}
.ta-ex__hint strong { color: var(--tp-text); font-weight: 500; }

/* --- where to read more --------------------------------------------------
   Pinned under the sections rather than being one of them: the links are the
   same on every page, and a numbered step implies something to do here. It took
   the Downloads section's place, which said "nothing to download" on all nine
   pages because no page ever had anything to put in it.
   ---------------------------------------------------------------------- */

.ta__docs {
  position: relative; z-index: 1;
  border-top: 1px solid var(--tp-line);
  padding: .8rem 1rem calc(.9rem + env(safe-area-inset-bottom));
  display: grid; gap: .4rem;
  background: var(--tp-ink);
}

.ta__docs__h {
  margin: 0 0 .1rem;
  font-family: var(--mono); font-size: .58rem;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--tp-dim);
}

.ta__doc {
  display: grid; gap: .05rem;
  padding: .45rem .6rem; border-radius: 6px;
  border: 1px solid var(--tp-line);
  background: var(--tp-panel);
  text-decoration: none;
  transition: border-color .15s, background .15s;
}
.ta__doc:hover { border-color: var(--tp-accent); background: var(--tp-raised); }
.ta__doc:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 1px; }

.ta__doc__label {
  font-size: .78rem; font-weight: 500; color: var(--tp-text);
}
.ta__doc__label::after { content: ' \2197'; color: var(--tp-dim); }
.ta__doc__note { font-size: .68rem; color: var(--tp-dim); line-height: 1.4; }

/* --- which lessons this page serves --------------------------------------
   Declared in every page's markup since the panel was written, and until now
   read only by the checks. A learner had no way to tell which part of the
   program a page belonged to.
   ---------------------------------------------------------------------- */

.ta-lessons {
  position: relative; z-index: 1;
  padding: .7rem 1rem .75rem;
  border-bottom: 1px solid var(--tp-line);
  background: var(--tp-ink);
}
.ta-lessons__h {
  margin: 0 0 .3rem; font-size: .58rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--tp-dim);
}
.ta-lessons__list {
  margin: 0; display: flex; flex-wrap: wrap; gap: .3rem .5rem;
  font-size: .7rem;
}
.ta-lessons__list .lesson-ref { color: var(--tp-dim); }
.ta-lessons__list .lesson-ref:hover { color: var(--tp-accent); }

/* --- exceptions simulator rules --------------------------------------------------
   The one section that does something rather than describing something.
   Deliberately plain: these are business situations a learner is choosing to
   practice against, not switches on a rig, so they read as sentences with a
   control attached rather than as a settings form.
   ---------------------------------------------------------------------- */

.ta-cond {
  display: grid; gap: .35rem;
  padding: .6rem 0;
  border-bottom: 1px solid var(--tp-line);
}
.ta-cond:last-of-type { border-bottom: 0; }

.ta-cond__label {
  margin: 0; font-size: .68rem; letter-spacing: .06em;
  color: var(--tp-dim);
}

.ta-cond__note {
  margin: 0 0 .5rem; font-size: .68rem; line-height: 1.55;
  color: var(--tp-dim);
}
.ta-cond__note:last-child {
  margin: .6rem 0 0; padding-top: .6rem;
  border-top: 1px solid var(--tp-line);
}

.ta-cond__choices { display: grid; gap: .15rem; }

.ta-cond__choice,
.ta-cond__toggle {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .3rem .45rem; border-radius: 5px;
  font-size: .76rem; color: var(--tp-text);
  cursor: pointer;
  transition: background .12s;
}
.ta-cond__choice:hover,
.ta-cond__toggle:hover { background: var(--tp-raised); }

.ta-cond__choice input,
.ta-cond__toggle input {
  accent-color: var(--tp-accent);
  margin: 0; flex: none; transform: translateY(1px);
}
.ta-cond__choice:has(input:checked) { background: var(--tp-raised); color: #fff; }
.ta-cond__choice input:focus-visible,
.ta-cond__toggle input:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 2px; }

.ta-cond__num {
  width: 7rem;
  background: var(--tp-ink); color: var(--tp-text);
  border: 1px solid var(--tp-line); border-radius: 5px;
  padding: .35rem .5rem;
  font-family: var(--mono); font-size: .76rem;
}
.ta-cond__num:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 1px; }

/* The way from a named endpoint to the page that explains it.
   Sized and shaped as the Copy button beside it — the two are a pair, and a link
   that looked like a link would out-shout the path it belongs to. */
.ta-api__docs {
  border: 1px solid var(--tp-line); color: var(--tp-dim);
  border-radius: 2px; padding: .1rem .35rem;
  font-family: var(--mono); font-size: .58rem; letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none; flex-shrink: 0;
}
.ta-api__docs:hover { color: var(--tp-accent); border-color: var(--tp-accent); }

/* Text to paste into a block. Wider line-height than a payload sample and a
   capped height: the email template is a page of HTML, and letting it run full
   length would push Activity off the bottom of the panel. */
.ta-snip { border-bottom: 1px solid var(--tp-line); padding-bottom: .6rem; margin-bottom: .6rem; }
.ta-snip:last-child { border-bottom: 0; margin-bottom: 0; }
.ta-snip__head {
  display: flex; align-items: center; gap: .5rem; padding: .45rem .55rem;
}
.ta-snip__label { color: var(--tp-text); font-size: .72rem; flex: 1; }
.ta-pre--snip { max-height: 15rem; overflow: auto; white-space: pre; }
