/* O2 AI Adviser, the website audit and the prototype studio: the workspace they share.
   Loaded only by the pages that have one, so product browsing carries none of it.
   Tokens, type and controls come from site.css; this file adds the three surfaces
   (a conversation, a brief or report beside it, a preview) and nothing decorative.

   The conversation is drawn as a chat: who you are talking to at the top, each side's
   words in a bubble on its own side, three dots while the adviser works, and one line
   to write in that grows with what is typed.

   Motion: 100-180 ms on a control, 240 ms on a message or a panel, opacity and a few
   pixels of travel. Nothing counts up, nothing loops except the three "working" dots,
   and with reduced motion asked for nothing moves at all. */

.ws { padding-bottom: var(--band); }
.ws[data-state="checking"] { min-height: 320px; }
.ws__off { max-width: 720px; padding: clamp(20px, 3vw, 32px); display: grid; gap: 10px; }
.ws__off p { color: var(--ink-2); max-width: 60ch; }
.ws__off-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
.ws__guided-head { padding-top: 8px; padding-bottom: 14px; display: grid; gap: 4px; }

.ws__grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr); gap: 20px; align-items: start; }
.ws__tabs { display: none; }
/* Three rows, each part in its own: who you are talking to, the conversation, the box to write in. Named by row so
   that a part which is hidden leaves an empty row instead of pulling the others up into the wrong one. */
.ws__chat > .ws__bar { grid-row: 1; }
.ws__chat > .ws__log { grid-row: 2; }
.ws__chat > .ws__composer { grid-row: 3; }
.ws__chat { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; min-height: min(72vh, 760px); max-height: 86vh; overflow: hidden; padding: 0; }
/* Before the first message there is nothing to scroll: the card is as tall as its words, and the box to write in is in view. */
.ws:not([data-started]) .ws__chat { min-height: 0; max-height: none; }
.ws__side { display: grid; gap: 20px; position: sticky; top: calc(var(--nav-h) + 16px); max-height: calc(100vh - var(--nav-h) - 32px); overflow: auto; overscroll-behavior: contain; border-radius: var(--r-l); }
.ws__panel { padding: 0; }
.ws__bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 20px; border-bottom: 1px solid var(--hair); }
.ws__h { font-size: .9375rem; font-weight: 600; letter-spacing: var(--trk-sub); }
.ws__ver { font-size: .8125rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.ws__quiet { color: var(--ink-3); font-size: .9375rem; padding: 18px 20px; }
.ws__lead { padding: 16px 20px 0; font-weight: 500; }

/* the session menu */
.ws__menu { position: relative; font-size: .875rem; }
.ws__menu summary { cursor: pointer; list-style: none; width: 36px; height: 36px; border-radius: 50%; color: var(--ink-2); display: grid; place-items: center; transition: background var(--t-fast) var(--ease), transform var(--t-press) ease-out; }
.ws__menu summary .i { width: 20px; height: 20px; }
.ws__menu summary:hover, .ws__menu[open] summary { background: var(--sunken); }
.ws__menu summary:active { transform: scale(.94); }
@media (pointer: coarse) { .ws__menu summary { width: 44px; height: 44px; } }

/* who you are talking to: the O2 mark, the adviser's name, and that it is an AI */
.ws__bar--chat { padding: 10px 12px 10px 16px; }
.ws__who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ws__avatar, .msg__avatar { display: grid; place-items: center; flex: none; border-radius: 50%; background: var(--ink); color: var(--on-ink); }
.ws__avatar { width: 40px; height: 40px; }
.ws__mark { width: 60%; height: auto; display: block; }
.ws__id { display: grid; gap: 1px; min-width: 0; }
.ws__sub { font-size: .8125rem; line-height: 1.35; color: var(--ink-3); }
.ws__menu summary::-webkit-details-marker { display: none; }
.ws__menu summary:hover { color: var(--ink); }
.ws__menu-list { position: absolute; right: 0; top: calc(100% + 6px); z-index: 5; min-width: 240px; padding: 8px; display: grid; gap: 2px; background: var(--surface); border-radius: var(--r-m); box-shadow: var(--shadow-lift); }
.ws__menu-list button { text-align: left; padding: 10px 12px; border-radius: var(--r-s); font: inherit; color: var(--ink); background: none; border: 0; cursor: pointer; min-height: 44px; }
.ws__menu-list button:hover { background: var(--sunken); }
.ws__menu-list p { padding: 8px 12px 4px; color: var(--ink-3); }

/* the conversation */
.ws__log { overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 20px; display: grid; gap: 14px; align-content: start; scroll-behavior: smooth; }
.ws__log:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ws__empty { display: grid; gap: 10px; padding: 8px 4px 4px; max-width: 56ch; }
.ws__empty p { color: var(--ink-2); }
.ws__empty .chips { margin-top: 6px; }
/* A message. Each side's words are in a bubble on its own side, with the corner nearest the speaker drawn tighter;
   the adviser's has the O2 mark beside it. Who spoke is also said to a screen reader (.msg__who). */
.msg { position: relative; display: grid; gap: 6px; max-width: min(86%, 62ch); animation: ws-in 240ms var(--ease) both; }
.msg--user { justify-self: end; transform-origin: 100% 100%; }
.msg--assistant { justify-self: start; grid-template-columns: 28px minmax(0, 1fr); column-gap: 8px; transform-origin: 0 100%; }
.msg__avatar { width: 28px; height: 28px; grid-column: 1; grid-row: 1 / span 2; align-self: end; }
.msg--assistant > .msg__body, .msg--assistant > .msg__activity, .msg--assistant > .msg__extra { grid-column: 2; min-width: 0; }
.msg--assistant > .msg__body { grid-row: 1; }
.msg--assistant > .msg__activity { grid-row: 2; }
.msg--assistant > .msg__extra { grid-row: 3; }
.msg__body { display: grid; gap: 8px; justify-self: start; max-width: 100%; padding: 10px 14px; border-radius: 20px; font-size: 1rem; line-height: 1.45; overflow-wrap: anywhere; }
:lang(th) .msg__body { line-height: 1.6; }
.msg__body:empty { display: none; }
.msg--assistant .msg__body { background: var(--sunken); border-bottom-left-radius: 6px; }
.msg--user .msg__body { justify-self: end; background: var(--accent); color: var(--on-accent); border-bottom-right-radius: 6px; white-space: pre-wrap; }
.msg__body ul, .msg__body ol { padding-left: 1.25em; display: grid; gap: 4px; }
.msg__body ul { list-style: disc; } .msg__body ol { list-style: decimal; }
/* A reply that is fixed rules and not the AI (guided mode): outlined instead of filled, and it says what it is. */
.msg--guided .msg__body { background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2); }
.msg__tag { font-size: .75rem; font-weight: 600; line-height: 1.4; color: var(--ink-3); }
/* While the adviser works: three dots in a bubble of their own, until its words arrive. What it is really doing
   (checking the catalogue, updating the brief) is said beside them; plain thinking is said to a screen reader only. */
.msg__activity { display: flex; align-items: center; gap: 10px; justify-self: start; font-size: .8125rem; color: var(--ink-3); }
.msg__dots { display: inline-flex; align-items: center; gap: 4px; padding: 14px; border-radius: 20px 20px 20px 6px; background: var(--sunken); }
.msg__dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3); animation: ws-dot 1.2s ease-in-out infinite; }
.msg__dots i:nth-child(2) { animation-delay: .16s; }
.msg__dots i:nth-child(3) { animation-delay: .32s; }
.msg__activity.is-plain .msg__doing { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.msg__body:not(:empty) ~ .msg__activity .msg__dots, .msg__body:not(:empty) ~ .msg__activity.is-plain { display: none; }
.msg__extra { display: grid; gap: 8px; margin-top: 2px; }
.msg__note { font-size: .875rem; padding: 10px 14px; border-radius: var(--r-m); max-width: 68ch; }
/* A line that belongs to nobody (the session ended, prototype design is on): centred and small, as in any chat. */
.ws__log > .msg__note { justify-self: center; text-align: center; font-size: .8125rem; line-height: 1.45; padding: 8px 14px; max-width: 52ch; }
.msg__note--info { background: var(--accent-soft); color: var(--alert-info); }
.msg__note--warn { background: var(--warn-soft); color: var(--alert-warn); }
.msg__fail { display: grid; gap: 10px; padding: 12px 14px; border-radius: 20px; background: var(--err-soft); color: var(--alert-err); max-width: 68ch; font-size: .9375rem; }
.ws__log > .msg__fail { justify-self: start; border-bottom-left-radius: 6px; max-width: min(86%, 62ch); }
.msg__actions { display: flex; flex-wrap: wrap; gap: 8px; }
/* What can be done next, under an answer: quick replies, lighter than the page's own buttons. */
.msg__actions .btn--s { font-weight: 550; }
.btn--s { min-height: 40px; padding: 8px 14px; font-size: .875rem; }
.msg__examples { display: grid; gap: 8px; list-style: none; padding: 0; }
.msg__example { display: grid; gap: 2px; padding: 12px 14px; border-radius: var(--r-m); box-shadow: inset 0 0 0 1px var(--hair-2); color: var(--ink); text-decoration: none; transition: box-shadow var(--t-fast) var(--ease), transform var(--t-press) ease-out; }
.msg__example:hover { box-shadow: inset 0 0 0 1px var(--accent); }
.msg__example:active { transform: scale(.99); }
.msg__example strong { font-size: .9375rem; }
.msg__example span { color: var(--ink-2); font-size: .875rem; }
.msg__example small { color: var(--ink-3); font-size: .8125rem; }

/* A conversation with an end. While too little is known the adviser's question comes with its answers to tap; when
   enough is, the conclusion is set out as a card: what fits and why, an example, and the next step. The card is the
   one thing in the conversation with the accent on its edge, so that the end reads as the end. */
.msg__ask { display: grid; gap: 8px; }
.msg__ask-q { font-size: .9375rem; font-weight: 600; color: var(--ink); }
.msg__quick { display: flex; flex-wrap: wrap; gap: 8px; }
/* An answer may be longer than the column is wide (Thai especially): it wraps inside its own button instead of pushing the page sideways. */
.msg__quick .chip { min-height: 40px; max-width: 100%; height: auto; padding-top: 8px; padding-bottom: 8px; white-space: normal; text-align: left; line-height: 1.35; }
@media (pointer: coarse) { .msg__quick .chip { min-height: 44px; } }
.chip--quiet { background: none; box-shadow: none; color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; padding: 0 8px; }
.chip--quiet:hover { color: var(--ink); }
.rec { display: grid; gap: 10px; min-width: 0; padding: 16px; border-radius: 20px; background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--accent), var(--shadow-card); animation: ws-in 320ms var(--ease) both; }
.rec__eyebrow { font-size: .75rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-press); }
:lang(th) .rec__eyebrow { letter-spacing: 0; font-size: .8125rem; }
.rec__list { list-style: none; padding: 0; display: grid; gap: 12px; }
.rec__item { display: grid; gap: 3px; }
.rec__head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.rec__name { font-size: 1.125rem; font-weight: 650; letter-spacing: -.01em; line-height: 1.25; color: var(--ink); text-decoration: none; }
a.rec__name:hover, a.rec__name:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.rec__tag { font-size: .75rem; font-weight: 600; line-height: 1.5; padding: 1px 9px; border-radius: var(--pill); background: var(--accent-soft); color: var(--alert-info); }
.rec__why { color: var(--ink-2); font-size: .9375rem; line-height: 1.45; }
:lang(th) .rec__why, :lang(th) .rec__line, :lang(th) .rec__foot { line-height: 1.6; }
.rec__line { font-size: .875rem; line-height: 1.45; color: var(--ink-2); }
.rec__line strong { color: var(--ink); font-weight: 600; }
.rec__example { margin-top: 2px; }
.rec__kicker { font-weight: 600; color: var(--ink-2) !important; }
.rec__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.rec__foot { font-size: .8125rem; line-height: 1.45; color: var(--ink-3); }
.rec__new { justify-self: start; font-size: .8125rem; font-weight: 500; color: var(--ink-3); min-height: 32px; text-decoration: underline; text-underline-offset: 3px; }
.rec__new:hover, .rec__new:focus-visible { color: var(--ink); }
@media (pointer: coarse) { .rec__new { min-height: 44px; } }
/* A recommendation that has been replaced, or no longer holds, stays to be read and steps back. */
.rec--old { box-shadow: inset 0 0 0 1px var(--hair-2); animation: none; }
.rec--old .rec__eyebrow, .rec--old .rec__name { color: var(--ink-3); }
.rec__old { font-size: .8125rem; font-weight: 600; color: var(--alert-warn); background: var(--warn-soft); padding: 6px 10px; border-radius: var(--r-s); }

/* the composer: always the last thing in the conversation's card, never under a floating layer. One line to write
   in, which grows with what is typed (the script sets its height), and a round button that sends it; while the
   adviser is answering, the button to stop is in its place. */
.ws__composer { display: grid; gap: 6px; padding: 10px 14px 14px; border-top: 1px solid var(--hair); background: var(--surface); }
.ws__field { display: flex; align-items: flex-end; gap: 6px; padding: 4px 4px 4px 16px; border-radius: 24px; background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2); transition: box-shadow var(--t-fast) var(--ease); }
.ws__field:focus-within { box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 4px var(--focus-halo); }
.ws__field textarea { flex: 1; min-width: 0; width: 100%; resize: none; overflow-y: hidden; margin: 0; padding: 8px 0; border: 0; outline: 0; background: none; color: var(--ink); font: inherit; font-size: 1rem; line-height: 1.4; }
/* The hint stays on one line however narrow the window: wrapped, it would make an empty box two lines tall. */
.ws__field textarea::placeholder { color: var(--ink-3); opacity: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws__field textarea[readonly] { color: var(--ink-3); }
.ws__round { flex: none; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; display: grid; place-items: center; cursor: pointer; transition: transform var(--t-press) ease-out, background var(--t-fast) var(--ease); }
.ws__round[hidden], .ws__round--send:disabled { display: none; }
.ws__round .i { width: 16px; height: 16px; }
.ws__round--send { background: var(--accent); color: var(--on-accent); }
.ws__round--send:hover { background: var(--accent-press); }
.ws__round--stop { background: var(--ink); color: var(--on-ink); }
.ws__round:active { transform: scale(.92); }
.ws__round:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (pointer: coarse) { .ws__round { width: 44px; height: 44px; } .ws__field { padding-left: 18px; } .ws__field textarea { padding: 11px 0; } }
.ws__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 0 6px; }
.ws__meta .field__hint { font-size: .75rem; color: var(--ink-3); }
/* How much has been typed is said only when it matters: near the limit, or over it. */
.ws__meta .counter:not(.is-near):not(.is-over) { display: none; }
.counter.is-over { color: var(--err); font-weight: 600; }
.ws__notice { color: var(--ink-3); max-width: 78ch; padding: 0 6px; }
/* What kind of adviser this is, when it is the small one that only answers questions: the first line of the
   conversation, centred and small like a chat's own notices. It is said before anything is asked, and then scrolls
   away with the rest. */
.ws__mode { justify-self: center; margin: 0; padding: 8px 14px; max-width: 54ch; border-radius: var(--r-m); background: var(--sunken); color: var(--ink-2); font-size: .8125rem; line-height: 1.45; text-align: center; }
/* Where a second model designs prototypes, the note carries the way to it: the words, then the button, which drops
   under them when there is no room beside. While that model is answering the note is tinted and stays in view, so
   who is answering, and the way back, are always there. */
.ws__mode:has(.ws__mode-go) { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 14px; max-width: 64ch; }
.ws__mode-text { flex: 1 1 18rem; min-width: 0; }
.ws__mode-go { flex: none; }
.ws__mode .link.ws__mode-go { font-size: inherit; color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; }
.ws__mode .link.ws__mode-go:hover, .ws__mode .link.ws__mode-go:focus-visible { color: var(--ink); }
.ws[data-studio] .ws__mode { position: sticky; top: 0; z-index: 1; background: var(--accent-soft); color: var(--alert-info); box-shadow: 0 0 0 1px var(--hair); }
.ws[data-studio] .ws__mode .link.ws__mode-go { color: inherit; }
.ws__alt { font-size: .8125rem; padding: 0 6px; }
.ws__alt .link { font-weight: 500; color: var(--ink-3); min-height: 32px; text-decoration: underline; text-underline-offset: 3px; }
.ws__alt .link:hover, .ws__alt .link:focus-visible { color: var(--ink); }
@media (pointer: coarse) { .ws__alt .link { min-height: 44px; } }

/* the brief */
.bs { padding: 14px 20px 0; display: grid; gap: 8px; }
.bs__h { font-size: .8125rem; font-weight: 600; color: var(--ink-3); letter-spacing: .01em; }
.bs__list { list-style: none; padding: 0; display: grid; gap: 2px; }
.bi { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; padding: 8px 0; border-top: 1px solid var(--hair); font-size: .9375rem; align-items: baseline; }
.bs__list > .bi:first-child, p.bi { border-top: 0; }
.bi__text { overflow-wrap: anywhere; color: var(--ink); }
a.bi__text { text-decoration: underline; text-underline-offset: 3px; }
.bi__tag { font-size: .75rem; color: var(--ink-3); white-space: nowrap; }
.bi--stated .bi__tag, .bi--confirmed .bi__tag { color: var(--ok); }
.bi--inferred .bi__tag { color: var(--warn); }
.bi__tag--assess { color: var(--warn); white-space: normal; text-align: right; }
.bi__sub { grid-column: 1 / -1; font-size: .8125rem; color: var(--ink-3); }
.bi__tools { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .8125rem; }
.bi__tools .link { min-height: 28px; font-weight: 500; color: var(--ink-3); }
.bi__tools .link:hover, .bi__tools .link:focus-visible { color: var(--ink); }
.bi__edit, .bi__add { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-top: 6px; }
.bi__edit input, .bi__add input { flex: 1 1 180px; min-height: 40px; padding: 8px 12px; border-radius: var(--r-s); border: 0; box-shadow: inset 0 0 0 1px var(--hair-2); background: var(--surface); color: var(--ink); font: inherit; font-size: .9375rem; }
.bi__edit input:focus-visible, .bi__add input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
.bs__foot { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 18px 20px 20px; margin-top: 14px; border-top: 1px solid var(--hair); }
.bs__foot .small { flex-basis: 100%; color: var(--ink-3); }
.bs__ok { font-size: .875rem; color: var(--ok); font-weight: 500; }

/* the prototype panel: the trusted surround of a generated prototype */
.ws__proto { margin-top: 20px; padding: 0; }
#ws-proto-body { display: grid; gap: 14px; padding: 18px 20px 20px; }
.proto__offer, .proto__build { display: grid; gap: 8px; padding: 16px; border-radius: var(--r-m); background: var(--accent-soft); justify-items: start; }
.proto__offer .small, .proto__build .small { color: var(--ink-2); }
.proto__stage-now { font-weight: 500; display: flex; align-items: center; gap: 8px; }
.proto__stage-now::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); animation: ws-pulse 1.1s ease-in-out infinite; }
.proto__log { padding-left: 1.25em; list-style: decimal; font-size: .875rem; color: var(--ink-2); display: grid; gap: 2px; }
.proto__head { display: grid; gap: 6px; }
.proto__tag { padding: 10px 14px; border-radius: var(--r-s); background: var(--warn-soft); color: var(--alert-warn); font-size: .9375rem; }
.proto__head .small { color: var(--ink-3); }
.proto__changed { font-size: .9375rem; color: var(--ink-2); }
.proto__logic { font-size: .9375rem; color: var(--ink-2); }
.proto__logic strong { color: var(--ink); font-weight: 600; }
.proto__failed { margin: 4px 0 0; padding-left: 18px; font-size: .9375rem; }
.proto__controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.proto__seg { display: inline-flex; padding: 3px; border-radius: var(--pill); background: var(--sunken); }
.proto__seg button { min-height: 38px; padding: 6px 14px; border: 0; border-radius: var(--pill); background: none; color: var(--ink-2); font: inherit; font-size: .875rem; font-weight: 500; cursor: pointer; transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
.proto__seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-card); }
.proto__tasks { display: grid; gap: 4px; font-size: .9375rem; color: var(--ink-2); max-width: 86ch; }
.proto__stage { border-radius: var(--r-m); box-shadow: inset 0 0 0 1px var(--hair-2); overflow: hidden; background: var(--sunken); transition: max-width 220ms var(--ease); max-width: 100%; }
.proto__stage[data-size="phone"] { max-width: 392px; margin: 0 auto; }
.proto__frame { display: block; width: 100%; height: 640px; border: 0; background: var(--surface); }
.proto__facts { display: grid; gap: 6px; }
.proto__fold { border-top: 1px solid var(--hair); padding: 8px 0; font-size: .9375rem; }
.proto__fold summary { cursor: pointer; font-weight: 550; min-height: 32px; display: flex; align-items: center; }
.proto__fold ul { padding: 6px 0 4px 1.25em; list-style: disc; color: var(--ink-2); display: grid; gap: 3px; }
.proto__fold small { color: var(--ink-3); }
.proto__facts > .small { color: var(--ink-3); padding-top: 8px; border-top: 1px solid var(--hair); }
.proto__foot { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; justify-content: space-between; padding-top: 14px; border-top: 1px solid var(--hair); }
.proto__change { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 8px; flex: 1 1 320px; max-width: 620px; }
.proto__change label { grid-column: 1 / -1; font-size: .875rem; font-weight: 600; }
.proto__change input { min-height: 40px; padding: 8px 12px; border-radius: var(--r-s); border: 0; box-shadow: inset 0 0 0 1px var(--hair-2); background: var(--surface); color: var(--ink); font: inherit; font-size: .9375rem; }
.proto__change input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
.proto__pick { display: flex; align-items: center; gap: 8px; font-size: .875rem; color: var(--ink-3); }
.proto__pick select { min-height: 36px; padding: 4px 10px; border-radius: var(--r-s); border: 0; box-shadow: inset 0 0 0 1px var(--hair-2); background: var(--surface); color: var(--ink); font: inherit; font-size: .875rem; }

/* sources */
.src { list-style: none; padding: 0 20px 18px; display: grid; gap: 10px; }
.src li { display: grid; gap: 1px; }
.src a { overflow-wrap: anywhere; }
.src__host { font-size: .8125rem; color: var(--ink-3); }
#ws-sources-body > .small { padding: 14px 20px 10px; color: var(--ink-3); }

/* The shortlist bar is fixed to the bottom of the window. Here that is where the composer and the brief's
   buttons are, so on these pages it steps aside; the shortlist itself is untouched and is on every other page. */
body.ws-page .tray { display: none; }

/* one panel at a time on a phone, chosen with labelled tabs */
@media (max-width: 899px) {
  .ws__grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .ws__tabs { display: flex; gap: 4px; padding: 4px; border-radius: var(--pill); background: var(--sunken); position: sticky; top: calc(var(--nav-h) + 8px); z-index: 3; }
  .ws__tabs [role="tab"] { flex: 1; min-height: 44px; padding: 8px 10px; border: 0; border-radius: var(--pill); background: none; color: var(--ink-2); font: inherit; font-size: .9375rem; font-weight: 500; cursor: pointer; position: relative; transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
  .ws__tabs [role="tab"][aria-selected="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-card); }
  .ws__dot { display: inline-block; width: 7px; height: 7px; margin-left: 6px; border-radius: 50%; background: var(--accent); vertical-align: middle; }
  .ws__side { position: static; max-height: none; overflow: visible; gap: 0; }
  .ws[data-tab="chat"] .ws__side, .ws[data-tab="brief"] .ws__chat, .ws[data-tab="sources"] .ws__chat, .ws[data-tab="demo"] .ws__chat, .ws[data-tab="demo"] .ws__side,
  .ws[data-tab="brief"] #ws-sources, .ws[data-tab="sources"] #ws-brief, .ws:not([data-tab="demo"]) .ws__proto { display: none; }
  .ws__proto { margin-top: 12px; }
  #ws-proto-body { padding: 14px 16px 16px; }
  .ws__tabs [role="tab"].has-news::after { content: ""; display: inline-block; width: 7px; height: 7px; margin-left: 6px; border-radius: 50%; background: var(--accent); vertical-align: middle; }
  .proto__frame { height: 560px; }
  /* The conversation fills the window under the header and the tabs, so the box to type in stays on screen
     and rises with the keyboard (dvh follows the visible area). */
  .ws[data-started] .ws__chat { min-height: 0; height: calc(100dvh - var(--nav-h) - 84px); max-height: none; }
  .ws__grid { scroll-margin-top: calc(var(--nav-h) + 8px); }
  /* Before the first message a phone shows only what is needed to write one: the examples and the box. The tabs,
     the session menu and the longer invitation have nothing to do yet, and would push the box off the first screen. */
  .ws:not([data-started]) .ws__tabs, .ws:not([data-started]) .ws__chat > .ws__bar, .ws__empty h3, .ws__empty p { display: none; }
  .ws:not([data-started]) .ws__log { padding-bottom: 14px; }
  .ws__empty { padding: 0; }
  body.ws-page .intro .lead { font-size: 1rem; }
  .ws__log { padding: 14px 12px 16px; }
  .ws__composer { padding: 8px 10px calc(10px + env(safe-area-inset-bottom)); }
  .ws__notice { font-size: .75rem; }
  .ws__bar { padding: 12px 16px; }
  .ws__bar--chat { padding: 8px 8px 8px 12px; }
  .ws__avatar { width: 36px; height: 36px; }
  .bs, .ws__quiet, .ws__lead { padding-left: 16px; padding-right: 16px; }
  .bs__foot { padding: 16px; }
  .msg { max-width: 92%; }
  .ws__log > .msg__fail { max-width: 100%; }
}

@keyframes ws-in { from { opacity: 0; transform: translateY(6px) scale(.98); } }
@keyframes ws-dot { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }
@keyframes ws-pulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
  .msg, .rec { animation: none; }
  .msg__dots i { animation: none; opacity: .7; }
  .ws__round, .ws__menu summary, .ws__field { transition: none; }
  .ws__log { scroll-behavior: auto; }
  .msg__example, .ws__tabs [role="tab"], .proto__seg button, .proto__stage { transition: none; }
  .proto__stage-now::before { animation: none; }
}
@media (prefers-contrast: more) {
  .ws__field, .bi__edit input, .bi__add input, .msg__example, .ws__menu summary { box-shadow: inset 0 0 0 2px var(--ink); }
  .msg__body, .msg__dots, .ws__mode { box-shadow: inset 0 0 0 1px var(--ink); }
  .rec { box-shadow: inset 0 0 0 2px var(--ink); }
}
@media print {
  .ws__composer, .ws__tabs, .ws__menu, .msg__actions { display: none; }
  .ws__chat, .ws__log { max-height: none; overflow: visible; }
}

/* ---- the website audit ------------------------------------------------------------------------------------ */
.au { display: grid; gap: 20px; }
.au__form, .au__work, .au__sec, .au__score, .au__limited { padding: clamp(18px, 2.4vw, 28px); display: grid; gap: 14px; max-width: 880px; }
.au__form input[type="text"] { width: 100%; min-height: 52px; padding: 12px 16px; border-radius: var(--r-m); border: 0; box-shadow: inset 0 0 0 1px var(--hair-2); background: var(--surface); color: var(--ink); font: inherit; font-size: 1.0625rem; }
.au__form input[type="text"]:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 4px var(--focus-halo); }
.au__will { font-size: .9375rem; color: var(--ok); overflow-wrap: anywhere; }
.au__what { display: grid; gap: 4px; padding: 14px 16px; border-radius: var(--r-m); background: var(--sunken); }
.au__what p { font-size: .9375rem; color: var(--ink-2); }
.au__how > summary { cursor: pointer; font-weight: 600; font-size: .9375rem; color: var(--ink); min-height: 44px; display: flex; align-items: center; }
.au__how[open] > summary { margin-bottom: 4px; }
.au__how p + p { margin-top: 8px; }
.au__wide { display: none; }
@media (min-width: 900px) { .au__wide { display: block; } .au__narrow { display: none; } .au__how > summary { display: none; } }
.au__confirm { display: grid; gap: 12px; padding-top: 14px; border-top: 1px solid var(--hair); justify-items: start; }
.au__confirm .field { width: min(100%, 420px); display: grid; gap: 6px; }
.au__confirm input[type="text"] { min-height: 44px; padding: 8px 12px; border-radius: var(--r-s); border: 0; box-shadow: inset 0 0 0 1px var(--hair-2); background: var(--surface); color: var(--ink); font: inherit; }
.au__head { display: grid; gap: 6px; max-width: 880px; scroll-margin-top: calc(var(--nav-h) + 16px); }
.au__head .small { color: var(--ink-3); overflow-wrap: anywhere; }
#au-report { display: grid; gap: 16px; }
.au__num { font-variant-numeric: tabular-nums; line-height: 1; }
.au__num strong { font-size: clamp(3rem, 2rem + 4vw, 4.5rem); font-weight: 650; letter-spacing: -.04em; }
.au__num span { font-size: 1.25rem; color: var(--ink-3); }
.au__score .small, .au__sec > .small { color: var(--ink-3); }
.au__reasons, .au__list, .au__pages, .au__crit, .au__fixes { list-style: none; padding: 0; display: grid; gap: 10px; }
.au__reasons { list-style: disc; padding-left: 1.25em; gap: 4px; color: var(--ink-2); }
.au__list li, .au__crit li { display: grid; gap: 2px; padding-top: 10px; border-top: 1px solid var(--hair); }
.au__list li:first-child, .au__crit li:first-child { border-top: 0; padding-top: 0; }
.au__list span, .au__why { color: var(--ink-2); font-size: .9375rem; }
.au__fix { display: grid; gap: 10px; padding: 16px 0 4px; border-top: 1px solid var(--hair); }
.au__fix:first-child { border-top: 0; padding-top: 0; }
.au__fix-h { font-size: 1.0625rem; font-weight: 600; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.au__tag { font-size: .75rem; font-weight: 600; padding: 2px 9px; border-radius: var(--pill); background: var(--sunken); color: var(--ink-2); }
.au__tag--critical, .au__tag--high { background: var(--err-soft); color: var(--alert-err); }
.au__tag--medium { background: var(--warn-soft); color: var(--alert-warn); }
.au__facts { display: grid; grid-template-columns: minmax(96px, auto) minmax(0, 1fr); gap: 6px 16px; font-size: .9375rem; }
.au__facts dt { color: var(--ink-3); }
.au__facts dd { overflow-wrap: anywhere; }
.au__addr { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .8125rem; overflow-wrap: anywhere; color: var(--ink-2); }
.au__ev { display: inline-flex; flex-wrap: wrap; gap: 4px 12px; font-size: .8125rem; }
.au__ev .link { min-height: 28px; font-weight: 500; color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; }
.au__st { justify-self: start; font-size: .75rem; font-weight: 600; padding: 2px 9px; border-radius: var(--pill); background: var(--sunken); color: var(--ink-2); }
.au__st--pass { background: var(--ok-soft); color: var(--ok); }
.au__st--fail { background: var(--err-soft); color: var(--alert-err); }
.au__st--partial { background: var(--warn-soft); color: var(--alert-warn); }
.au__pages li { display: block; font-size: .875rem; }
.au__pages small { color: var(--ink-3); }
.au__drawer { width: min(92vw, 620px); max-height: 86vh; padding: 0; border: 0; border-radius: var(--r-l); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-float); }
.au__drawer::backdrop { background: var(--scrim); }
#au-drawer-body { display: grid; gap: 10px; padding: 22px; }
.au__shot { max-width: 220px; height: auto; border-radius: var(--r-s); box-shadow: 0 0 0 1px var(--hair-2); }
@media (max-width: 899px) { .au__facts { grid-template-columns: minmax(0, 1fr); gap: 2px; } .au__facts dd { margin-bottom: 8px; } }
@media print { .au__form, .au__ev, .msg__actions, .nav, .foot { display: none !important; } .proto__fold > ul { display: grid !important; } }

/* The teaching page's preview (src/js/adviser.js PREVIEW): the same adviser, without the site's header and footer
   around it, under a line that says it is a preview and sends nothing. */
html[data-preview] #nav, html[data-preview] .foot, html[data-preview] .intro, html[data-preview] .crumbs { display: none !important; }
html[data-preview] main { padding-top: 12px; }
.preview-bar { margin: 0 0 12px; padding: 8px 12px; border-radius: var(--r-m); background: var(--warn-soft); color: var(--ink); font-size: .8125rem; line-height: 1.45; }
.preview-stop { margin-top: 8px; }
/* "Start my project" could not open Stripe's page: said under the buttons, in words (server/pay.js). */
.rec__fail { margin: 6px 0 0; color: var(--err); font-size: .875rem; }
.rec__fail:empty { display: none; }

/* The brief's version on its tab (Phase 6). */
.ws__tabv { white-space: pre; font-size: .8125rem; font-weight: 500; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* Jump to latest: over the end of the conversation, only while the visitor reads further up (Phase 6). */
.ws__chat > .ws__jump { grid-row: 2; grid-column: 1; align-self: end; justify-self: center; margin-bottom: 10px; z-index: 2; box-shadow: var(--shadow-card); background: var(--surface); }
.ws__parked { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 8px; }
