.writing-tool-controls {
    display: flex;
    gap: 10px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--line);
    background: var(--surface2);
}

.writing-tool-controls label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--muted);
    font-size: 13px;
    font-weight: 650;
}

.writing-tool-controls select,
.writing-tool-controls input {
    min-height: 34px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface);
    color: var(--ink);
    padding: 6px 10px;
    font: inherit;
    font-weight: 500;
}

.paraphrase-controls {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.paraphrase-controls label {
    align-items: stretch;
    flex-direction: column;
    gap: 5px;
}

.paraphrase-controls .wide {
    grid-column: 1 / -1;
}

.writing-tool-review {
    margin-top: 18px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
    box-shadow: 0 14px 35px rgba(29, 52, 41, .08);
    overflow: hidden;
}

.writing-review-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--line);
    background: var(--surface2);
}

.writing-review-title {
    margin: 0;
    color: var(--ink);
    font-size: 18px;
    font-weight: 750;
}

.writing-review-meta {
    color: var(--muted);
    font-size: 13px;
}

.writing-review-actions {
    display: flex;
    gap: 8px;
}

.writing-tool-button {
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface);
    color: var(--ink);
    padding: 7px 11px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 650;
}

.writing-tool-button.primary {
    border-color: var(--green);
    background: var(--green);
    color: #fff;
}

.writing-tool-button:disabled {
    cursor: wait;
    opacity: .6;
}

/* green fills keep white text in light; dark ink on the brighter dark-theme
   green, the same treatment core.css gives .greenBtn */
:root[data-theme="dark"] .writing-tool-button.primary,
:root[data-theme="dark"] .paraphrase-segment button.active { color: #0D1F17; }

.grammar-score {
    display: inline-grid;
    place-items: center;
    min-width: 46px;
    min-height: 46px;
    border-radius: 50%;
    background: var(--green-tint);
    color: var(--green-deep);
    font-weight: 800;
}

.grammar-issue-list,
.sentence-review-list {
    display: grid;
    gap: 10px;
    padding: 14px;
}

.grammar-issue,
.sentence-review {
    border: 1px solid var(--line);
    border-left: 4px solid var(--issue-color, #4b8c74);
    border-radius: 12px;
    padding: 12px 14px;
    background: var(--surface);
}

.grammar-issue.is-dismissed {
    opacity: .55;
}

.grammar-issue-top,
.sentence-review-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.grammar-category {
    color: var(--issue-color, #4b8c74);
    font-size: 12px;
    font-weight: 750;
    text-transform: capitalize;
}

.grammar-change {
    margin: 8px 0 5px;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.grammar-change del {
    background: var(--danger-bg);
    color: var(--danger);
    padding: 1px 3px;
    text-decoration-thickness: 2px;
}

.grammar-change ins {
    background: var(--green-tint);
    color: var(--green-deep);
    padding: 1px 3px;
    text-decoration: none;
}

.grammar-explanation,
.sentence-original {
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}

.grammar-rewrite-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}

.grammar-rewrite-controls select {
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface);
    padding: 6px 9px;
}

.grammar-rewrite-preview {
    flex-basis: 100%;
    color: var(--ink);
}

.sentence-variant-preview {
    margin-bottom: 7px;
    border-radius: 8px;
    background: var(--surface2);
    padding: 9px 11px;
}

/* an accepted fix is always the green mark of the sample's .iss.fixed —
   the earlier per-category tints read as red or blue leftovers */
.grammar-applied {
    border-radius: 3px;
    background: var(--diff-bg);
    box-shadow: inset 0 -2px 0 var(--diff-line);
    color: inherit;
    padding: 0 2px;
}

.paraphrase-applied {
    border-radius: 3px;
    background: var(--green-tint);
    color: inherit;
    padding: 0 2px;
}

.sentence-paraphrase {
    margin-top: 7px;
    color: var(--ink);
    line-height: 1.55;
}

.word-alt-trigger {
    display: inline;
    border: 0;
    border-bottom: 1px dotted var(--green);
    background: transparent;
    color: inherit;
    padding: 0;
    cursor: pointer;
    font: inherit;
}

.word-alt-trigger:hover {
    background: var(--green-tint);
}

.sentence-variants {
    display: grid;
    gap: 7px;
    margin-top: 10px;
}

.sentence-variant {
    width: 100%;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface2);
    color: var(--ink);
    padding: 9px 11px;
    text-align: left;
    cursor: pointer;
}

.writing-empty {
    padding: 22px;
    color: var(--muted);
    text-align: center;
}

/* Grammar Checker: ported from the field-tested Node page. */
.grammar-controls {
    align-items: center;
    flex-wrap: wrap;
    padding: 12px 20px;
}

.grammar-goal-label {
    margin-right: 4px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

/* the goal pills carry .style-tab as well and take their look from the shared
   pill styles — only the filter chips still need the local rule */
.grammar-filter {
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    padding: 7px 13px;
    cursor: pointer;
    font: inherit;
    font-size: 12px;
    font-weight: 650;
}

/* .h1-welcome (the centred signed-in greeting) lives in core.css now — the
   main page carries the same heading and does not load this file */

/* the spacer, not an auto margin, pushes the note right: when the row wraps
   the note lands on its own row left-aligned, as in the sample */
.ctl-spacer { flex: 1; }
.grammar-goal-note {
    color: var(--muted);
    font-size: 11px;
}

.grammar-score-panel {
    display: flex;
    /* The sample's .score-strip is a wrapping row, but it has the full width of
       the page to spend; ours has half a tool panel. Laid out as a row it put
       the score, a single column of four subscores and the tone chip side by
       side, and the strip stood four rows tall. Folded — score, the four
       subscores on one line, tone last — it reads as the sample does. */
    flex-direction: column;
    align-items: stretch;
    gap: 13px;
    /* no side margins: the sample's .score-strip shares the panel padding
       with the filter row and the reviewed text */
    margin: 14px 0 10px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    padding: 15px;
    box-shadow: 0 7px 18px rgba(24, 58, 43, .08);
}

.grammar-score-panel[hidden],
.grammar-category-filters[hidden] {
    display: none;
}

/* number and the "Writing score" caption sit side by side, as the sample's
   .score-main (the old grid dropped the caption under the digit) */
.grammar-main-score {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.grammar-main-number {
    color: var(--green-deep);
    font-family: Georgia, serif;
    font-size: 42px;
    line-height: 1;
}

.grammar-main-score small {
    color: var(--muted);
    font-size: 9px;
    letter-spacing: .13em;
    line-height: 1.35;
    text-transform: uppercase;
}

.grammar-score-delta {
    margin-left: 5px;
    color: var(--green);
    font-size: 10px;
    font-weight: 700;
}

/* the sample's .subscores is a wrapping flex row with a 78px floor per column,
   and that is what this is now. The grid it replaces (repeat(auto-fit,
   minmax(78px, 1fr))) still drew the tone chip over the Style column on an
   older iOS: auto-fit and minmax are the two pieces of the declaration a Safari
   that predates them throws away, and a grid left without columns lays its
   items out over each other. Flex items cannot overlap at all — short of room
   they wrap, which is the sample's own behaviour. min-width: 0 lets the box
   shrink: a flex item's automatic minimum is its content width otherwise. */
.grammar-subscores {
    display: flex;
    flex-wrap: wrap;
    flex: 1 1 auto;
    min-width: 0;
    gap: 12px;
}

.grammar-subscore {
    flex: 1 1 78px;
    min-width: 78px;
}

.grammar-subscore > div {
    display: flex;
    justify-content: space-between;
    color: var(--muted);
    font-size: 10px;
    font-weight: 700;
}

.grammar-subscore b {
    color: var(--ink);
}

.grammar-score-bar {
    display: block;
    height: 4px;
    margin-top: 5px;
    border-radius: 999px;
    background: var(--line);
    overflow: hidden;
}

.grammar-score-bar i {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--green);
}

.grammar-tone {
    /* the sample's .tone-chip keeps to the right edge of its row, and on its
       own row that is the right edge of the strip. The column stack stretches
       its children, so the chip has to claim its content width back */
    align-self: flex-end;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 7px 11px;
    color: var(--muted);
    font-size: 11px;
    white-space: nowrap;
}

.grammar-tone b {
    color: var(--ink);
}

.grammar-category-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
    /* flush with the score strip and the text, as the sample's .cat-filters */
    padding: 0 0 10px;
}

.grammar-filter {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
}

.grammar-filter i {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

/* active chip per the sample's .cf-chip.active: ink border at its normal
   width plus a tinted fill — the extra inset ring read as a double-thick
   outline */
.grammar-filter.active {
    border-color: var(--ink);
    color: var(--ink);
    background: var(--surface2);
}

.grammar-category-filters .grammar-accept-all {
    margin-left: auto;
    border-radius: 999px;
}

#GrammarChecker .quillOutput {
    white-space: normal;
}

/* air between the reviewed text and the dashed footer line, matching the
   input side's gap */
#GrammarChecker .humanResult .quillOutput,
#AIParaphraser .humanResult .quillOutput {
    margin-bottom: 10px;
}

.grammar-inline-issue {
    display: inline;
    border: 0;
    border-bottom: 2px solid var(--issue-color);
    border-radius: 0;
    background: transparent;
    color: inherit;
    padding: 0;
    cursor: pointer;
    font: inherit;
    line-height: inherit;
    text-align: inherit;
}

.grammar-inline-issue.severity-improve {
    border-bottom-style: dashed;
}

.grammar-inline-issue.severity-suggest {
    border-bottom-style: dotted;
}

.grammar-inline-issue:hover,
.grammar-inline-issue:focus-visible {
    background: color-mix(in srgb, var(--issue-color) 10%, transparent);
    outline: none;
}

/* the sample's .sent-flag: a small clarity-coloured pill inside the sentence */
.grammar-long-sentence {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 5px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: rgba(124, 58, 237, .11);
    color: #7c3aed;
    padding: 1px 8px;
    cursor: pointer;
    vertical-align: 1px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .04em;
    white-space: nowrap;
    transition: border-color .18s;
}

.grammar-long-sentence:hover,
.grammar-long-sentence:focus-visible {
    background: rgba(124, 58, 237, .18);
    outline: 1px solid rgba(124, 58, 237, .4);
}

.grammar-review-detail {
    margin: 0 18px 12px;
    border: 0;
    border-radius: 12px;
    box-shadow: none;
}

.grammar-detail {
    border: 1px solid var(--line);
    border-left: 4px solid var(--issue-color);
    border-radius: 12px;
    background: var(--surface);
    padding: 12px 14px;
}

.grammar-detail-badges,
.grammar-detail-actions {
    display: flex;
    align-items: center;
    gap: 7px;
}

.grammar-detail-badges span {
    border-radius: 999px;
    background: var(--surface2);
    color: var(--muted);
    padding: 3px 8px;
    font-size: 10px;
    font-weight: 750;
}

.grammar-detail-badges span:first-child {
    background: color-mix(in srgb, var(--issue-color) 12%, var(--surface));
    color: var(--issue-color);
}

.grammar-detail-actions {
    margin-top: 10px;
}

.grammar-applied {
    transition: background .2s ease;
}

#GrammarChecker .quillOutput.no-hl .grammar-applied {
    background: transparent;
    box-shadow: none;
}

.grammar-review-detail .writing-empty {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--green-tint);
}

/* AI Paraphraser: token-level review contract from the Node tool. */
.paraphrase-controls {
    align-items: center;
    grid-template-columns: auto auto 1fr;
    padding: 12px 20px;
}

.paraphrase-control-row,
.paraphrase-segment,
.paraphrase-refine {
    display: flex;
    align-items: center;
    gap: 8px;
}

.paraphrase-control-label,
.paraphrase-refine > span {
    color: var(--muted);
    font-size: 11px;
    font-weight: 750;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.paraphrase-segment {
    gap: 0;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 22px;
    background: var(--surface);
}

.paraphrase-segment button,
.paraphrase-refine button,
.paraphrase-advanced-toggle {
    border: 0;
    background: transparent;
    color: var(--ink);
    padding: 8px 12px;
    cursor: pointer;
    font: inherit;
    font-size: 12px;
    font-weight: 650;
}

.paraphrase-segment button.active {
    border-radius: 18px;
    background: var(--green);
    color: #fff;
    box-shadow: 0 4px 10px rgba(20, 122, 89, .2);
}

.paraphrase-advanced-toggle {
    justify-self: end;
    color: var(--green);
}

.paraphrase-advanced {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    width: 100%;
    padding-top: 4px;
}

.paraphrase-advanced[hidden] {
    display: none;
}

/* the sample's .psent: the hovered sentence lifts on a faint green wash, which
   is what tells you a whole sentence is a target of its own */
.paraphrase-sentence {
    position: relative;
    border-radius: 6px;
    transition: background .2s;
}

.paraphrase-sentence:hover { background: rgba(14, 123, 84, .05); }

/* Short desktop viewports: the static fits the field and the submit into the
   first screen by compact sizing, so these two tools mirror it here — the
   empty field gives up some height. The quick actions keep the shared
   stacked column of the other tools (they briefly had a one-row style of
   their own here, which read as a different component). */
@media (min-width: 961px) and (max-height: 1050px) {
    /* the exact empty-field height comes from --wt-empty-editor: JS measures
       how far the submit sits past the fold on this screen and shrinks the
       field accordingly (72px floor) — a fixed number only fits one screen */

    /* the placeholder used to drop to 14px here, which bought no room at all
       (it is absolutely positioned and auto-height, so its type never moved
       the field) and only made these two read a size smaller than the same
       placeholder on the humanizer and the detector — all four share 15.5px */

    /* The hero used to give back part of its padding here (14px top, 22px
       bottom against the shared 30/36), which put the heading and the whole
       card under it 16px higher than on the humanizer and the detector —
       switching tools jumped. The empty field already yields to the viewport
       through --wt-empty-editor, so all four pages keep the same hero and the
       submit still clears the fold. The controls bar keeps its short-screen
       padding, but from core.css, so the humanizer's bar matches. */
    body.grammar .hero-grid .list-splash,
    body.paraphraser .hero-grid .list-splash { margin-bottom: 4px; }
    body.grammar .hero-copy .sub,
    body.paraphraser .hero-copy .sub { margin-bottom: 8px; }
}

/* First screen on any desktop height: the empty field yields to the viewport
   (the detector does the same with its card cap). The body-scoped selectors
   outrank the async-loaded 170px rules regardless of load order. */
@media (min-width: 961px) {
    body.grammar #GrammarChecker .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container,
    body.paraphraser #AIParaphraser .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container {
        height: var(--wt-empty-editor, 170px);
    }
}

/* ----------------------------------------------------------------------------
   Grammar: sentence wrappers, floating issue card and the rewrite box,
   all ported from the sample (.gsent / .gpop / .ab-*)
   -------------------------------------------------------------------------- */
.grammar-sent { border-radius: 6px; transition: background .2s; }
.grammar-sent.active { background: var(--green-tint); box-shadow: 0 0 0 3px var(--green-tint); }

.grammar-sent-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-left: 5px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
    font-size: 11px;
    vertical-align: 1px;
    opacity: 0;
    transition: opacity .2s, color .2s, border-color .2s;
}

.grammar-sent:hover .grammar-sent-btn,
.grammar-sent.active .grammar-sent-btn,
.grammar-sent.show-rewrite .grammar-sent-btn { opacity: 1; }
.grammar-sent-btn:hover { color: var(--green); border-color: var(--green); }
/* touch screens have no hover — there the ↻ appears when the sentence is
   tapped (JS toggles .show-rewrite), same as the paraphraser's button */

.grammar-inline-issue.sel {
    background: color-mix(in srgb, var(--issue-color) 14%, transparent);
}

.gpop {
    position: absolute;
    z-index: 60;
    width: min(320px, 88vw);
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
    box-shadow: var(--shadow-pop);
    padding: 14px;
    animation: wt-pop .18s ease;
}

.gp-badges { display: flex; align-items: center; gap: 6px; margin-bottom: 9px; }

.gp-cat {
    border-radius: 999px;
    color: #fff;
    padding: 2px 9px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.gp-sev {
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--muted);
    padding: 2px 9px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.gp-change { margin-bottom: 7px; font-size: 15px; font-weight: 600; line-height: 1.5; }
.gp-change .old { color: var(--danger); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.gp-change .new { color: var(--green-deep); }
.gp-change .arr { margin: 0 4px; color: var(--muted); font-weight: 400; }
.gp-why { margin-bottom: 12px; color: var(--muted); font-size: 13.5px; line-height: 1.55; }
.gp-actions { display: flex; gap: 8px; }

.gp-accept {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 0;
    border-radius: 10px;
    background: var(--green);
    color: #fff;
    padding: 9px 12px;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 13.5px;
    font-weight: 700;
    transition: background .18s;
}

.gp-accept:hover { background: var(--green-deep); }
:root[data-theme="dark"] .gp-accept { color: #0D1F17; }

.gp-dismiss {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--line);
    border-radius: 10px;
    background: transparent;
    color: var(--muted);
    padding: 9px 14px;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 13.5px;
    font-weight: 700;
    transition: .18s;
}

.gp-dismiss:hover { color: var(--ink); border-color: var(--ink); }

/* rewrite modes inside the sentence box */
.ab-modes { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }

.ab-mode {
    border: 1.5px solid var(--line);
    border-radius: 99px;
    background: var(--surface2);
    color: var(--muted);
    padding: 5px 13px;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 12.5px;
    font-weight: 700;
    transition: .18s;
}

.ab-mode:hover { border-color: var(--green); color: var(--green); }
.ab-mode.active { background: var(--green); border-color: var(--green); color: #fff; }
:root[data-theme="dark"] .ab-mode.active { color: #0D1F17; }

.altbox .ab-preview {
    margin-bottom: 10px;
    border: 1.5px solid var(--line);
    border-radius: 11px;
    background: var(--surface2);
    color: var(--ink);
    padding: 11px 13px;
    font-size: 14.5px;
    line-height: 1.65;
}

.ab-preview .ph { color: var(--placeholder); font-style: italic; }
.gpop .ab-preview {
    margin-bottom: 12px;
    border: 1.5px solid var(--line);
    border-radius: 11px;
    background: var(--surface2);
    padding: 11px 13px;
    font-size: 13.5px;
    line-height: 1.55;
}

.ab-apply {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 0;
    border-radius: 10px;
    background: var(--green);
    color: #fff;
    padding: 8px 16px;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 13.5px;
    font-weight: 700;
    transition: background .18s;
}

.ab-apply:hover:not(:disabled) { background: var(--green-deep); }
.ab-apply:disabled { opacity: .5; cursor: not-allowed; }
:root[data-theme="dark"] .ab-apply { color: #0D1F17; }

/* "all done" strip under the text. The sample's panel foot carries a 10px top
   margin of its own; ours pushes itself down with margin-top:auto, which is 0
   once the panel is full — so the note has to hold the gap above the dashed
   line itself, or it sits right on it */
.clean-note {
    display: none;
    align-items: center;
    gap: 8px;
    margin: 12px 0;
    border: 1px solid var(--diff-line);
    border-radius: 12px;
    background: var(--green-tint);
    color: var(--green-deep);
    padding: 8px 13px;
    font-size: 13px;
    font-weight: 700;
}

.clean-note.show { display: flex; }

/* word popover: floats right under the clicked change chip, as in the sample */
.wpop {
    position: absolute;
    z-index: 60;
    min-width: 220px;
    /* never wider than the phone viewport minus the JS clamp margin */
    max-width: min(290px, calc(100vw - 24px));
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
    box-shadow: var(--shadow-pop);
    padding: 12px;
    animation: wt-pop .18s ease;
}

.wpop .wp-title {
    display: block;
    margin-bottom: 8px;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.wpop .wp-title.wp-loading {
    margin: 8px 0 0;
    text-transform: none;
    letter-spacing: normal;
    font-size: 12px;
}

.wpop .wp-opt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--ink);
    padding: 8px 10px;
    cursor: pointer;
    text-align: left;
    font-family: var(--font-body);
    font-size: 14.5px;
    font-weight: 600;
    transition: background .15s;
}

.wpop .wp-opt:hover { background: var(--green-tint); }
.wpop .wp-opt .tag { font-family: var(--font-mono); font-size: 10px; color: var(--muted); }
.wpop .wp-opt.orig { color: var(--muted); }
.wpop .wp-opt.orig .tag { color: var(--warn); }
.wpop .wp-opt.current { background: var(--surface2); cursor: default; }
.wpop .wp-opt.current .tag { color: var(--green); }

/* sentence alternatives: a green-bordered box right under the result text,
   the picked sentence stays highlighted while it is open */
.paraphrase-sentence.active {
    background: var(--green-tint);
    box-shadow: 0 0 0 3px var(--green-tint);
}

.altbox {
    border: 1.5px solid var(--green);
    border-radius: 14px;
    background: var(--surface);
    padding: 14px 16px;
    margin-top: 12px;
    animation: wt-pop .22s ease;
}

.altbox .ab-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
}

.altbox .ab-head b { font-size: 13.5px; }

.altbox .ab-close {
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--muted);
    padding: 2px 6px;
    cursor: pointer;
    font-size: 17px;
    line-height: 1;
}

.altbox .ab-close:hover { color: var(--ink); background: var(--surface2); }
.altbox .ab-preview { color: var(--muted); font-size: 13.5px; }

.alt-opt {
    display: block;
    width: 100%;
    margin-bottom: 8px;
    border: 1.5px solid var(--line);
    border-radius: 11px;
    background: var(--surface2);
    color: var(--ink);
    padding: 11px 13px;
    cursor: pointer;
    text-align: left;
    font-family: var(--font-body);
    font-size: 14.5px;
    line-height: 1.65;
    transition: border-color .18s, background .18s;
}

.alt-opt:hover { border-color: var(--green); background: var(--green-tint); }
.alt-opt:last-child { margin-bottom: 0; }

.alt-opt .alt-tag {
    display: block;
    margin-bottom: 3px;
    color: var(--green);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

@keyframes wt-pop {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: none; }
}

/* streaming render, as in the sample: a pulsing status line while the result
   types itself in behind a caret */
.stream-status {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 8px;
    color: var(--muted);
    font-size: 13.5px;
}

.stream-status::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--green);
    animation: wt-blinkdot 1s ease infinite;
}

.stream-caret {
    display: inline-block;
    width: 2px;
    height: 1.1em;
    margin-left: 1px;
    background: var(--green);
    vertical-align: -2px;
    animation: wt-blinkdot .8s ease infinite;
}

@keyframes wt-blinkdot {
    0%, 100% { opacity: 1; }
    50% { opacity: .25; }
}

/* same look as the humanizer's diff marks and the sample's mark.chg: soft
   tint with an inset underline, no border box around every change */
.paraphrase-change {
    border: 0;
    border-radius: 4px;
    background: var(--diff-bg);
    box-shadow: inset 0 -2px 0 var(--diff-line);
    color: inherit;
    padding: 1px 3px;
    cursor: pointer;
    font: inherit;
    transition: background .15s;
}

/* the mark's own UA colours would win over the inherited ink in dark mode */
mark.paraphrase-change { color: var(--ink); }
.paraphrase-change:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }

.paraphrase-change:hover,
.paraphrase-change:focus-visible {
    background: var(--mark-bg);
    box-shadow: inset 0 -2px 0 #D9B92C;
}

/* the sample's .frozen-w: a 2px dotted green underline and the help cursor,
   and nothing at all once the highlighting toggle is off */
.paraphrase-frozen {
    border-bottom: 2px dotted var(--green);
    cursor: help;
}

#AIParaphraser .quillOutput.no-hl .paraphrase-frozen { border-bottom: none; }

#AIParaphraser .quillOutput.no-hl .paraphrase-change {
    background: transparent;
    box-shadow: none;
    padding: 0;
}

/* the sample's .sent-btn, the same control the grammar checker already uses:
   a bordered square on the surface, muted until hovered — the green circle
   this used to be read as a badge stuck to the end of every sentence */
.paraphrase-sentence-variants {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-left: 5px;
    vertical-align: 1px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
    font-size: 11px;
    /* hidden until the sentence is hovered (or tapped on touch screens — JS
       puts .show-rewrite on the tapped sentence), as the sample's .sent-btn */
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s, visibility .2s;
}

.paraphrase-sentence:hover .paraphrase-sentence-variants,
.paraphrase-sentence.active .paraphrase-sentence-variants,
.paraphrase-sentence.show-rewrite .paraphrase-sentence-variants {
    opacity: 1;
    visibility: visible;
}

.paraphrase-sentence-variants:hover { color: var(--green); border-color: var(--green); }
/* with the highlighting toggle off the result is plain text, so the control
   goes with the marks (the sample hides it the same way) */
#AIParaphraser .quillOutput.no-hl .paraphrase-sentence-variants { display: none; }

.paraphrase-facts {
    /* the sample's .meaning-chip: content-wide at the panel padding, not a
       full-width bar with margins of its own */
    display: inline-flex;
    align-items: center;
    width: fit-content;
    margin: 10px 0 0;
    border: 1px solid var(--diff-line);
    border-radius: 11px;
    background: var(--green-tint);
    color: var(--green-deep);
    padding: 10px 12px;
    font-size: 12px;
    font-weight: 700;
}

.paraphrase-facts.warn {
    border-color: var(--warn);
    background: var(--mark-bg);
    color: var(--warn);
}

.paraphrase-refine {
    flex-wrap: wrap;
    /* flush with the result text, as the sample's .refine row */
    margin: 10px 0 0;
    padding-bottom: 10px;
    border-bottom: 1px dashed var(--line);
}

.paraphrase-refine button {
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
    padding: 7px 11px;
}

.paraphrase-refine button:hover {
    border-color: var(--diff-line);
    background: var(--green-tint);
}

.paraphrase-detail {
    padding: 16px 18px;
}

.paraphrase-detail-title {
    margin-bottom: 9px;
    color: var(--ink);
    font-size: 13px;
    font-weight: 750;
}

.paraphrase-detail-current {
    margin-bottom: 10px;
    color: var(--ink);
    font-size: 16px;
}

.paraphrase-detail-options {
    display: grid;
    gap: 7px;
}

.paraphrase-detail-options button {
    width: 100%;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface2);
    color: var(--ink);
    padding: 9px 11px;
    text-align: left;
    cursor: pointer;
}

.paraphrase-detail-options small {
    float: right;
    color: var(--muted);
}

@media (max-width: 780px) {
    .writing-tool-controls,
    .paraphrase-controls {
        display: grid;
        grid-template-columns: 1fr;
    }

    /* the sample's phone block: a smaller score digit, and dropdown items
       sized for a finger */
    .grammar-main-number { font-size: 32px; }
    .style-dropdown .dropdown-panel .item { padding: 11px 12px; font-size: 15px; }

    .paraphrase-controls .wide {
        grid-column: auto;
    }

    .writing-review-head {
        align-items: flex-start;
        flex-direction: column;
    }

    /* two per row on a phone, and the floor goes so the pair always fits */
    .grammar-subscore {
        flex: 1 1 calc(50% - 6px);
        min-width: 0;
    }

    /* the sample's phone rule lets the tone chip go left */
    .grammar-tone {
        align-self: flex-start;
    }

    .grammar-category-filters .grammar-accept-all {
        margin-left: 0;
    }

    .paraphrase-control-row,
    .paraphrase-advanced {
        align-items: stretch;
        grid-template-columns: 1fr;
    }

    .paraphrase-control-row {
        display: grid;
    }

    .paraphrase-segment {
        width: fit-content;
        max-width: 100%;
        overflow-x: auto;
    }

    .paraphrase-advanced-toggle {
        justify-self: start;
    }
}

/* ----------------------------------------------------------------------------
   Tool controls bar (paraphraser), per the sample: style, strength, length and
   the advanced toggle share one wrapping row across the whole tool. They used to
   live inside the half-width input panel on a three-column grid, where the
   strength and length pills ran past the panel edge and were clipped.
   -------------------------------------------------------------------------- */
.tool-controls {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
    padding: 12px 22px; border-bottom: 1px solid var(--line);
}
.tool-controls .rewrite-toolbar {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 0; margin: 0; border: 0; flex: 0 1 auto;
}
.tool-controls .rewrite-toolbar .label,
.tool-controls .paraphrase-control-label,
.tool-controls .grammar-goal-label {
    font-family: var(--font-mono); font-size: 11px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
/* the goal block used to be a padded row of its own; dissolved, its label, pills
   and note become items of the bar, and the .ctl-spacer keeps the note to the
   right edge while the row fits, as the sample's .ctl-spacer + .ctl-note do */
.tool-controls .grammar-controls { display: contents; }
.tool-controls .grammar-goal-note {
    font-family: var(--font-mono); font-size: 11px; color: var(--muted);
}
/* the grid the block used inside the panel would keep it three columns wide */
.tool-controls .paraphrase-controls {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
    padding: 0; flex: 1 1 auto; grid-template-columns: none;
}
/* the advanced toggle keeps to the right edge of the bar, as in the sample */
.tool-controls .paraphrase-advanced-toggle { margin-left: auto; }
.tool-controls .paraphrase-advanced { flex: 1 0 100%; }

@media (max-width: 720px) {
    .tool-controls { padding: 10px 14px; gap: 8px 12px; }
    .tool-controls .paraphrase-advanced-toggle { margin-left: 0; }
}

/* [hidden] is an attribute, so a class that sets display wins over it — the
   refine row carries display:flex from the rule it shares with the control rows
   and stayed on screen above an empty result. */
.paraphrase-refine[hidden],
/* the facts chip sets display:inline-flex, which outranks the UA rule the
   hidden attribute relies on — without this the empty chip showed as a bare
   green-bordered pill in the result panel */
.paraphrase-facts[hidden],
.paraphrase-control-row[hidden],
.paraphrase-advanced-count[hidden],
.paraphrase-segment[hidden] { display: none; }

/* Quick actions use the shared stacked component from core.css, so all four
   tools present the same full-width "Try a sample / Paste here / Upload file"
   column (the one-row variant the samples had was dropped by request). */

/* ----------------------------------------------------------------------------
   Control labels and segments, ported from the sample (.ctl-label / .seg /
   .spill). The previous rules used hardcoded greys and greens, so they also
   ignored the dark theme; these use the design tokens the sample itself uses.
   -------------------------------------------------------------------------- */
.tool-controls .rewrite-toolbar .label,
.tool-controls .paraphrase-control-label,
.tool-controls .grammar-goal-label {
    font-family: var(--font-mono); font-size: 10.5px; font-weight: 400;
    letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
    white-space: nowrap;
}

.tool-controls .paraphrase-segment {
    display: inline-flex; gap: 2px; padding: 3px;
    background: var(--surface2); border: 1.5px solid var(--line); border-radius: 999px;
}
/* line-height: normal is what the sample's buttons get from the UA sheet — ours
   inherit the body's 1.65 from the global button reset, which made every pill in
   the bar ~4px taller than the sample's and the rows uneven. */
.tool-controls .paraphrase-segment button {
    font-family: var(--font-body); font-size: 12.5px; font-weight: 700; line-height: normal;
    color: var(--muted); background: transparent; border: none; border-radius: 999px;
    padding: 5px 12px; cursor: pointer; white-space: nowrap;
    transition: background .18s, color .18s;
}
.tool-controls .style-tab { font-size: 13px; line-height: normal; }
.tool-controls .paraphrase-segment button:hover { color: var(--ink); }
/* Strength reads as the accent, Length as the neutral one — same split as the
   sample, where .seg button.active is green and .seg-len button.active is dark */
.tool-controls .paraphrase-segment button.active {
    background: var(--green); color: #fff; box-shadow: 0 2px 8px rgba(14, 123, 84, .3);
}
.tool-controls .paraphrase-segment[data-paraphrase-setting="length"] button.active {
    background: var(--panel-dark); color: #F4F3EC; box-shadow: none;
}
:root[data-theme="dark"] .tool-controls .paraphrase-segment button.active { color: #0D1F17; }
:root[data-theme="dark"] .tool-controls .paraphrase-segment[data-paraphrase-setting="length"] button.active {
    background: #E9EAE2; color: #131511;
}

/* The picked pill (green, not the shared dark one) moved to core.css — the
   main page carries the humanizer's style row and does not load this file. */

/* Style pills stay on a single row (.style-pills in the sample is nowrap): the
   ones that no longer fit are dropped at each step down, and the full list stays
   reachable through "All ▾". Wrapping them made the bar three rows tall on a
   phone. The counts mirror the sample's breakpoints. */
.tool-controls .style-tabs { flex-wrap: nowrap; min-width: 0; }
@media (max-width: 1000px) { .tool-controls .style-tabs > button:nth-of-type(n+7) { display: none; } }
@media (max-width: 840px) { .tool-controls .style-tabs > button:nth-of-type(n+6) { display: none; } }
@media (max-width: 680px) { .tool-controls .style-tabs > button:nth-of-type(n+5) { display: none; } }
@media (max-width: 520px) { .tool-controls .style-tabs > button:nth-of-type(n+4) { display: none; } }
@media (max-width: 400px) { .tool-controls .style-tabs > button:nth-of-type(n+3) { display: none; } }
/* the goal names are longer than the style names, so on a phone the row keeps
   just General and Academic — the rest stay under "All" */
@media (max-width: 560px) { .tool-controls #goalPills > button:nth-of-type(n+3) { display: none; } }
/* whether the "All" menu shows is measured in JS (syncStyleDropdowns):
   it appears exactly when at least one pill is hidden, whatever the
   breakpoints or the number of styles */

/* Phone: 44px touch targets for the quick actions and the submit, as in the
   sample's ≤560 block. Strength and Length are the exception — label and segment
   together are wider than the card, so the segment drops to its own row and its
   buttons shrink to share it instead of running past the edge. The style pills
   keep their desktop size too: bumped to 9/15px they towered over the Strength
   and Length rows beside them. */
@media (max-width: 560px) {
    .tool-controls { gap: 8px 12px; padding: 10px 14px; }
    /* the goal note drops to its own line instead of being squeezed to the right */
    .tool-controls .grammar-goal-note { margin-left: 0; flex: 1 0 100%; }
    .tool-controls .paraphrase-control-row { flex-wrap: wrap; width: 100%; }
    .tool-controls .paraphrase-segment { max-width: 100%; }
    .tool-controls .paraphrase-segment button { padding: 7px 10px; font-size: 12px; }
}

/* .paraphrase-controls was a flex container of its own, so the bar saw it as one
   big item next to the style group and pushed it to a second line. Dissolving it
   lets Style and Strength share a row, as they do in the sample. */
.tool-controls .paraphrase-controls { display: contents; }
.tool-controls .paraphrase-control-row { display: flex; align-items: center; gap: 8px; }
.tool-controls { gap: 10px 14px; padding: 12px 20px; }

/* Grammar: the empty field matches the sample's textarea (170px, 130 on phones)
   instead of the shared 100px, so the quick actions sit right under the text. */
#GrammarChecker .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container {
    height: 170px;
}
@media (max-width: 720px) {
    #GrammarChecker .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container {
        height: 130px;
    }
}


/* Advanced toggle, per the sample's .adv-btn: sliders glyph, label, optional
   count, chevron that flips when the panel opens. */
.tool-controls .paraphrase-advanced-toggle {
    display: inline-flex; align-items: center; gap: 7px;
    background: none; border: none; cursor: pointer;
    font-family: var(--font-body); font-size: 13px; font-weight: 700; line-height: normal;
    color: var(--green); padding: 6px 2px;
}
.tool-controls .paraphrase-advanced-toggle:hover { text-decoration: underline; }
.tool-controls .paraphrase-advanced-toggle .adv-chev { display: inline-flex; transition: transform .25s; }
.tool-controls .paraphrase-advanced-toggle[aria-expanded="true"] .adv-chev { transform: rotate(180deg); }
.tool-controls .paraphrase-advanced-count {
    font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
    padding: 1px 7px; border-radius: 99px;
    background: var(--green); color: #fff;
}
:root[data-theme="dark"] .tool-controls .paraphrase-advanced-count { color: #0d1f17; }

/* ----------------------------------------------------------------------------
   Advanced panel (.advanced in the sample): freeze terms as chips on the left,
   custom instructions with example chips on the right. The chips write the
   comma-separated value the backend reads into the hidden #paraphraseFreeze.
   -------------------------------------------------------------------------- */
.tool-controls .paraphrase-advanced {
    grid-template-columns: 1fr 1fr; gap: 18px;
    margin: 12px -20px -12px; padding: 16px 20px;
    border-top: 1px solid var(--line); background: var(--surface2);
    animation: paraphrase-adv-pop .25s ease;
}
@keyframes paraphrase-adv-pop {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: none; }
}
.adv-col b {
    display: flex; align-items: center; gap: 7px;
    font-size: 13.5px; margin-bottom: 4px;
}
.adv-col .hint {
    display: block; margin-bottom: 8px;
    font-size: 12.5px; color: var(--muted);
}
.chip-zone {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 38px;
    padding: 6px 8px; border: 1.5px solid var(--line); border-radius: 12px;
    background: var(--surface); cursor: text; transition: border-color .2s;
}
.chip-zone:focus-within { border-color: var(--green); }
.chip-zone input {
    flex: 1; min-width: 120px; padding: 4px 2px;
    border: none; background: transparent; outline: none;
    /* weight named for the same reason as .custom-inp: the controls rule puts
       500 on every input in the bar, and the sample's two fields are both plain */
    font-family: var(--font-body); font-size: 14px; font-weight: 400; color: var(--ink);
}
.chip-zone input::placeholder { color: var(--placeholder); }
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 6px 3px 11px; border: 1px solid var(--diff-line); border-radius: 99px;
    background: var(--green-tint); color: var(--green-deep);
    font-size: 13px; font-weight: 700;
    animation: paraphrase-adv-pop .18s ease;
}
.chip button {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; border: none; border-radius: 50%;
    background: none; color: var(--green-deep); font-size: 14px; line-height: 1; cursor: pointer;
}
.chip button:hover { background: rgba(14, 123, 84, .18); }
.chip-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.chip-suggest[hidden] { display: none; }
.chip-suggest .cs-label {
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted);
}
.chip-ghost {
    padding: 3px 11px; border: 1.5px dashed var(--line); border-radius: 99px;
    background: var(--surface); color: var(--muted);
    font-family: var(--font-body); font-size: 12.5px; font-weight: 700; line-height: normal;
    cursor: pointer; transition: .18s;
}
.chip-ghost:hover { border-style: solid; border-color: var(--green); color: var(--green); }
/* the selector carries .writing-tool-controls because the generic control rule
   at the top of this file sets `font: inherit` on every input inside the bar,
   and one class heavier beats a bare .custom-inp — the instructions field was
   inheriting the panel's 16.5px while the freeze field beside it stayed at the
   sample's 14px */
.writing-tool-controls .custom-inp,
.custom-inp {
    width: 100%; min-height: 38px; padding: 10px 14px;
    border: 1.5px solid var(--line); border-radius: 12px; background: var(--surface);
    font-family: var(--font-body); font-size: 14px; font-weight: 400; color: var(--ink);
    outline: none; transition: border-color .2s;
}
.custom-inp:focus { border-color: var(--green); }
.custom-inp::placeholder { color: var(--placeholder); }
.custom-examples { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
@media (max-width: 760px) {
    .tool-controls .paraphrase-advanced { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
    .tool-controls .paraphrase-advanced { margin: 10px -14px -10px; padding: 14px; }
}

/* ----------------------------------------------------------------------------
   Phone, first screen (pairs with the block at the end of ds/core.css)

   The paraphraser and the checker carry two control rows the humanizer does not
   — strength, length, goals — so they start the fight for the fold about 90px
   behind. The empty field gives back what it can spare: 88px still holds the
   two-line placeholder, and the field grows the moment anything is typed.
   -------------------------------------------------------------------------- */
@media (max-width: 720px) {
    #AIParaphraser .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container,
    #GrammarChecker .original-block:has(.custom-placeholder:not(.hidden)) .quill-editor-container {
        height: 88px;
    }
    .tool-controls { padding: 9px 14px; gap: 7px 12px; }
    .tool-controls .rewrite-toolbar { gap: 8px; }

    /* the segmented controls lose a little padding rather than a option: every
       label stays, the rows just stop being 39px tall apiece */
    .paraphrase-segment button,
    .paraphrase-refine button { padding: 6px 11px; }
    .paraphrase-advanced-toggle { padding: 5px 10px; }
    .paraphrase-controls { gap: 7px; }
}

/* ----------------------------------------------------------------------------
   Phone: strength and length move under the options toggle

   Four control rows is what keeps the paraphraser's button off the first screen,
   and these two are the rows a visitor rarely touches before the first run —
   Medium and Same are the defaults for a reason. Collapsed they cost nothing;
   opened they appear under the toggle, above the freeze and instruction fields,
   as one options block.

   The rows keep their place in the markup, so every id and listener stays where
   it was; only the order and the visibility change.
   -------------------------------------------------------------------------- */
@media (max-width: 720px) {
    .paraphrase-controls { display: flex; flex-direction: column; align-items: stretch; }
    .paraphrase-controls .paraphrase-advanced-toggle { order: 1; align-self: flex-start; }
    .paraphrase-controls .paraphrase-control-row { order: 2; }
    .paraphrase-controls .paraphrase-advanced { order: 3; }

    /* closed panel, closed rows — :has keys off the same hidden attribute the
       toggle flips, so there is no second source of truth */
    .paraphrase-controls:has(.paraphrase-advanced[hidden]) .paraphrase-control-row { display: none; }

    /* the checker's hint wraps to a line of its own and explains a control that
       explains itself — the pills are labelled Academic, Business, Casual */
    .grammar-goal-note { display: none; }
    .tool-controls { padding-top: 8px; padding-bottom: 8px; }
}

/* The submit is the same button on all four tools, at every width: 42px tall,
   15.5px, 11/24 padding, straight from .quillFooter in core.css. The checker
   and the paraphraser used to sit a step above it on the grounds that "Check my
   grammar" is the longest label — but the tab strip switches between the four
   in place, and a button that changes size between tabs reads as a different
   product rather than a longer word. */

/* iOS Safari zooms the page in when it focuses a field whose text is under
   16px, and the zoom stays put — a horizontal scroll on a page that fits
   perfectly well otherwise. 16px is the threshold, not a design decision. */
@media (max-width: 720px) {
    .chip-zone input { font-size: 16px; }
}
