/* assets/css/scroll-desk.css — the Scroll Desk's identity, returned.
   Spec: docs/superpowers/specs/2026-08-03-hookcraft-identity-design.md
   Record: mockups/11-hookcraft-palettes.html
   Recovered byte-for-byte from the retired skin at 0385f29^
   on Ritu's ruling, 2026-08-15; the culled endpoint did not return with it.

   Replaces social-frame.css (the "Flow" skin), which carried the periwinkle
   indigo #5B6CF0, the 135-degree blue-to-purple gradient, a blurred glow orb,
   two fonts on this repo's own off-system list, and a thick accent bar down the
   input. Ritu, 2026-08-02: "spare me the AI look. Don't want a single element to
   look like AI did it."

   TWO LAWS, and they are the whole design:

   1. COLOUR IS STATE, NEVER DECORATION. Nothing wears an accent at rest. The
      accent appears only where something is happening or can be pressed. The
      tell was never the colour, it was accent used as jewellery.
   2. FLAT. No gradient, no glow, no soft shadow, anywhere.

   ONE MEASURED CONSTRAINT, and it survived the move to dark. On the bone ground
   it was teal against signal red at 1.31:1. On this ground it is the gold hero
   block against the teal pills at 1.01:1, which is worse: they are all but
   identical in luminance. THEY NEVER TOUCH. The ground always sits between
   them, which is why the block and the pill row are separated by the input and
   never share an edge.

   Fonts load nowhere here. HookCraft uses the house faces. */

[data-theme="social"] {
  /* --- the identity. Ritu, 2026-08-03: "I think a dark background works best.
     Not this", then "for the word SCROLL and the pills, use the colours from
     the Social landing page", then "don't change anything else."

     So the ground and both accents are social-dark.css's, byte for byte, and
     nothing else about this sheet moved. HookCraft stops being a third colour
     system and sits with social.html and FrameWork, which the spec had written
     down as an accepted cost and is now simply not a cost.

     The bone palette could not come across intact, and this is why. Measured on
     this ground the house teal #187079 falls to 3.23:1 and FAILS AA for text,
     because it is a dark colour. The landing's lifted teal reads 7.54:1. Every
     pair below was measured, not assumed. --- */
  --hot:  #E5301B;   /* SHOUTS. 4.07:1 here, graphic/large only. Now carries the
                        stopper angle marks alone: the hero block went to the
                        landing's mark on his instruction. That mark was gold
                        until 2026-09-09 and is riso pink now. */

  /* --- ground and accents: social-dark.css's values, unchanged.
     tests/social-hook-skin.test.js pins these to that file so HookCraft cannot
     silently drift off the Social suite again. --- */
  --paper:       #16171A;
  --paper-deep:  #1F2024;
  --paper-warm:  #1F2024;
  --ink:         #ECE7DC;   /* 14.54:1 on the ground */
  --ink-soft:    #C3BDB0;
  --quiet:       #989185;   /* 5.74:1 */
  --rule:        #34353A;   /* decorative card border */
  --rule-soft:   #2A2B2F;
  --edge:        #66686D;   /* border of anything you can touch, 3.21:1 */
  --accent:      #56B6BF;   /* WORKS: buttons, selected pill, focus. 7.54:1 */
  --accent-deep: #1E4F80;
  --mark:        #FF7FB2;   /* the landing's hero emphasis. 7.62:1 on the ground,
                               and 7.62:1 for ground-ink sitting ON it, so the
                               block reads both ways round. Riso pink replaced
                               the gold #CBA15A on Ritu's ruling of 2026-09-09;
                               it is social-dark.css's value, byte for byte, and
                               tests/scroll-desk-skin.test.js pins it there. */
  --good:        #86A86E;
  --warn:        #D98C53;
  --brand-rule:  #3576B5;
  --cta-fill:    #56B6BF;
  --cta-ink:     #16171A;   /* ground ink on the teal fill, 7.54:1 */
  --overlay-bg:  rgba(0,0,0,.62);
  --value-mark:  rgba(255,127,178,.20);
  --mast-paper:  #E9EDED;   /* the masthead strip stays daylight, see below */
  --navy:        #082A4C;
}

/* ---- BRAND CHROME, and it is the one thing the dark ground could not simply
   inherit. editorial-frame.css has .tool-masthead FOLLOW the page background
   ("so masthead and body match"). On this ground that took the navy wordmark,
   the 2px navy brand rule and the navy Teach pill with it: navy #082A4C on
   #16171A measures 1.29:1, and all three all but vanished in the first dark
   render.

   social.html already solves both ends of a dark page, and this mirrors it
   rather than inventing a third treatment. The masthead is a daylight strip, so
   the fixed wordmark asset reads unaltered and the navy rule returns. The
   colophon stays on the dark ground and inverts the same asset in CSS, exactly
   as .foot .copy img does on the landing. The logo is a fixed asset and is
   never re-cut; the correction is CSS, per DESIGN-SYSTEM.md. ---- */
[data-theme="social"] .tool-masthead {
  background:  var(--mast-paper);
  --paper:     var(--mast-paper);
  --ink:       #1A1717;
  --ink-soft:  #2F2A26;
  --quiet:     #6B6259;
  --rule:      #C9C3B7;
  --edge:      #8F8778;
  /* The DAY teal, not the lifted one. #56B6BF on this daylight strip is 1.71:1
     and would fail outright; the Day teal reads 6.04:1 since the 2026-08-03
     deepening. The strip is a daylight island, so it takes daylight values. */
  --accent:    #156169;
  --cta-fill:  #082A4C;
  --cta-ink:   #FBFAF6;
  color: var(--ink);
}
[data-theme="social"] .tool-foot .copy img { filter: brightness(0) invert(1); opacity: .55; }

/* ---- layout: the shared product frame, left-aligned.
   --prose, NOT --measure: --measure is 62ch and caps the rewrite OUTPUT column
   product-wide (see the note in editorial-frame.css). Redefining it here would
   have reached every tool. ---- */
.hook-stage { max-width: var(--frame); margin: 0 auto; padding: 3rem 0 5rem; }
.hook-hero  { margin-bottom: 2rem; }
.hook-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(var(--t-7), 6vw, 4rem); line-height: 1.02; letter-spacing: -.03em;
  /* 1rem under the hero, the same gap .lede carries on FrameWork. Ritu,
     2026-09-13: "the gap between the hero and the text in both: not good at
     all", and "symmetry is the essence of this project". It was .6rem here
     and 1.6rem there. */
  color: var(--ink); margin: 0 0 1rem;
}
/* The hero block wears the landing's hero-emphasis gold (--mark), on Ritu's
   instruction 2026-08-03. On the landing that gold is italic TEXT; here it is a
   block, which is HookCraft's own form and did not change. Measured both ways:
   gold on ground 7.50:1, ground-ink on gold 7.50:1, so it is a real pass at any
   size rather than the large-text-only pass the signal-red block had. */
.hook-title .blk { display: inline-block; background: var(--mark); color: var(--paper); padding: 0 .32em .08em; }
.hook-sub {
  font-family: var(--font-body); font-size: clamp(var(--t-3), 2.2vw, var(--t-4));
  line-height: 1.5; color: var(--quiet); margin: 0; max-width: var(--prose);
}
/* The standfirst's emphasis, 2026-09-14. Ritu, on his phone with the two
   social desks side by side: FrameWork's last line is emphasised and this
   one's is not, and he chose to have both.

   It is the SAME mechanism, not a second one. social-dark.css line 419 does
   this with `.lede em { color: var(--ink); font-style: normal; }`, and this
   page does not load that sheet. Measured, FrameWork's em resolves to
   rgb(236, 231, 220), which is this theme's own --ink, #ECE7DC. So the two
   emphases are the same colour against the same --quiet ground, reached by
   the same two declarations.

   Not italic, deliberately, and that is inherited rather than invented: the
   emphasis in this suite is a lift in brightness, not a change of face. */
.hook-sub em { color: var(--ink); font-style: normal; }

/* ---- the input. AT REST IT CARRIES NO COLOUR.
   The old skin ran `border-left: 3px solid var(--accent)` here. That bar is one
   of the tells, and it does not come back. Focus is the edge itself going teal
   and thick, with the padding reduced by 1px so nothing shifts. No ring. ---- */
.hook-input {
  /* Full width of the stage, which is the original. It was briefly capped to
     --prose on reading-measure grounds (144 characters to a line against a
     comfortable 45 to 75), and Ritu reverted it the same day: "the input box is
     just for inputs. Nobody's going to read what is inside. It's copy and paste.
     The output will be divided into two columns anyway." The measure argument
     applies to prose you READ, and nobody reads this box. Leave it wide. */
  width: 100%;
  min-height: 7rem; padding: 1rem 1.1rem;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--edge); border-radius: var(--box);
  font-family: var(--font-body); font-size: var(--t-3); line-height: 1.5;
  resize: vertical; outline: none;
}
.hook-input::placeholder { color: var(--quiet); }
.hook-input:focus { border: 2px solid var(--accent); padding: calc(1rem - 1px) calc(1.1rem - 1px); }

/* ---- controls keep the house pill (Ritu, 2026-08-03). The hard edges live in
   the colour blocks, the input and the cards, which are square in the house
   sheet too, so this is not an exception to anything. ---- */
.platform-pills { display: inline-flex; gap: .25rem; border: 1px solid var(--edge); border-radius: var(--pill); padding: .25rem; }
.platform-pill {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .1em;
  text-transform: uppercase; color: var(--quiet); background: transparent;
  border: 0; border-radius: var(--pill); padding: .45rem .9rem; cursor: pointer;
  min-height: var(--touch-min);
  transition: transform var(--press-out) var(--press-ease);
}
.platform-pill[aria-pressed="true"] { color: var(--cta-ink); background: var(--accent); --ico-color:currentColor; }
/* Post / Thread / Long post carried no press before this (measured
   2026-09-10). --press-light, the tokens editorial-frame.css declares and
   this sheet reads because it always loads after that one (same order
   .hook-go already relies on, two rules above). A shape choice, not the run:
   .hook-go beside it is the one that takes --press-deep. */
.platform-pill:active:not(:disabled) {
  transform: scale(var(--press-light));
  transition: transform var(--press-in) var(--press-ease);
}

.hook-go {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .14em;
  text-transform: uppercase; color: var(--cta-ink); background: var(--accent);
  --ico-color: currentColor;
  border: 0; border-radius: var(--pill); padding: .8rem 1.6rem; cursor: pointer;
  min-height: var(--touch-min);
  transition: background .15s ease, transform var(--press-out) var(--press-ease);
}
/* The hover fill is a deep navy; --cta-ink is near-black, so the label read
   2.12:1 hovered in every theme. The words go light and the mark follows them.
   Measured 2026-08-05, 1440x900. */
.hook-go:hover:not(:disabled) { background: var(--accent-deep); color: var(--ink); --ico-color:currentColor; }

/* ---- THREE STATES, NOT TWO.

   Ritu, 2026-08-17: "But why is the Hook me button still dim?"

   It was `:disabled { opacity: .5 }`, and `disabled` was carrying two entirely
   different meanings with one paint. NOTHING TO DO YET (the box is empty, you
   have just arrived) and WORKING RIGHT NOW (you pressed it, the desk is
   writing) both rendered as the same half-erased button. Measured on live prod
   before the fix: at rest the label sat at 2.81:1 against its own fill, going
   to 7.54:1 the moment a character was typed. The loudest control on the page
   greeted you below the legibility floor and looked broken rather than
   waiting, then looked broken again for the whole seventeen seconds of a run.

   The signal that separates them was already here: scroll-desk.js sets
   aria-busy="true" on this button when a run starts and drops it when the run
   ends, and no stylesheet in the product had ever read it.

   OPACITY IS GONE FROM THIS CONTROL ENTIRELY, which is the same ruling that
   chose the press: opacity means dead in this product and a live control must
   not borrow that paint. Waiting is a real colour instead. ---- */

/* WAITING — disabled, and not busy. A deliberate unlit control, not a faded
   one. --paper-deep ground, --quiet label, a hairline in --rule: all existing
   tokens, no new colour. Measured 5.21:1, which clears the 4.5:1 floor that
   the old 2.81:1 did not. The inset shadow rather than a border because
   .hook-go is border:0 and a real border would shift the label by a pixel. */
.hook-go:disabled:not([aria-busy="true"]) {
  background: var(--paper-deep);
  color: var(--quiet);
  box-shadow: inset 0 0 0 var(--hairline) var(--rule);
  --ico-color: currentColor;
  opacity: 1;
  cursor: default;
}

/* WORKING — disabled because it is running. Full strength, and it breathes so
   the desk is visibly still going. This is NOT the progress indicator he ruled
   out on 2026-08-17 ("not for the rewrite button itself to get activated"):
   that ruling was about the instant of the press, and this carries no progress
   claim, which is honest because the desk cannot know how far along it is. */
.hook-go[aria-busy="true"] {
  opacity: 1;
  cursor: progress;
  animation: hook-working 1.6s ease-in-out infinite;
}
@keyframes hook-working {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(.82); }
}
/* Reduced motion takes the breathing away and leaves the button lit. The state
   is still readable: the label says Checking… or Writing… on its own. */
@media (prefers-reduced-motion: reduce) {
  .hook-go[aria-busy="true"] { animation: none; }
}
/* Press feedback. The same law and the same value the editorial run button
   already carries (editorial-frame.css:1204): on the press only, never on the
   disabled state, so the working state that follows does not keep the button
   shrunk. Ritu, 2026-08-16: "the buttons need to be a little responsive." */
.hook-go:active:not(:disabled) {
  transform: scale(var(--press-deep));
  transition: background .15s ease, transform var(--press-in) var(--press-ease);
}
/* The label changes to Checking… and Writing… while the desk works. Those
   words are longer than Hook me, so without a width floor the button resizes
   under the finger that just pressed it. The floor is set from the longest of
   the three labels; check it by pressing the button, not by reading this. */
.hook-go { min-width: 11rem; text-align: center; }

/* The suite's clear control, speaking this row's language. Everything else in
   the action row is mono at .72rem, so the shared control's display face would
   be the only other voice in a row of four buttons. Shape, colour, mark and
   behaviour are the suite's; only the face changes. */
[data-theme="social"] .clear-btn {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .1em;
  color: var(--quiet); border-color: var(--edge); gap: .4rem;
  transition: color .2s ease, border-color .2s ease,
              transform var(--press-out) var(--press-ease);
}
[data-theme="social"] .clear-btn:hover { color: var(--ink); border-color: var(--accent); }
/* Secondary control: it keeps the depth it had (--press-light) and takes the
   shared curve, so Clear releases like the Hook me beside it without becoming
   as loud. The two depths are declared in icons.css. */
[data-theme="social"] .clear-btn:active:not(:disabled) {
  transform: scale(var(--press-light));
  transition: color .2s ease, border-color .2s ease,
              transform var(--press-in) var(--press-ease);
}

.hook-upload {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .1em;
  text-transform: uppercase; color: var(--quiet); background: transparent;
  border: 1px solid var(--edge); border-radius: var(--pill); padding: .55rem 1rem;
  cursor: pointer; min-height: var(--touch-min);
}
.hook-upload:hover { color: var(--ink); border-color: var(--accent); }
.hook-thumb-wrap[hidden] { display: none; }
.hook-thumb-wrap { position: relative; display: inline-block; margin-top: .9rem; }
.hook-thumb { max-height: 120px; max-width: 100%; border-radius: 0; border: 1px solid var(--rule); display: block; }
.hook-thumb-wrap button { position: absolute; top: -8px; right: -8px; width: 24px; height: 24px; border-radius: var(--pill); border: 0; background: var(--accent); color: var(--cta-ink); --ico-color: currentColor; font-size: 1rem; line-height: 1; cursor: pointer; }

/* ---- stoppers. Square cards, flat, no shadow. Two across on wide screens so
   the frame is used rather than one card stretched across it. ---- */
.hook-stoppers { display: grid; gap: 1rem; margin-top: 1.5rem; }
@media (min-width: 62rem) { .hook-stoppers { grid-template-columns: 1fr 1fr; } }
.stopper { background: var(--paper); border: 1px solid var(--rule); border-radius: 0; padding: 1.25rem 1.4rem; }
/* The angle label takes a small mark rather than a colour chip: the shout colour
   appears at label scale without a third bright colour entering the palette. */
.stopper-angle {
  display: flex; align-items: center; gap: .45rem;
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink);
}
.stopper-angle::before { content: ''; width: .6rem; height: .6rem; background: var(--hot); flex: none; }
.stopper-line {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(var(--t-4), 3.2vw, var(--t-6)); line-height: 1.25;
  color: var(--ink); margin: .4rem 0 .7rem; max-width: var(--prose);
}
.stopper-acts { display: flex; gap: .5rem; flex-wrap: wrap; }
.stopper-acts button {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .08em;
  text-transform: uppercase; color: var(--quiet); background: transparent;
  border: 1px solid var(--edge); border-radius: var(--pill); padding: .35rem .7rem;
  cursor: pointer; min-height: var(--touch-min);
}
.stopper-acts button:hover { color: var(--ink); border-color: var(--accent); }
/* the one confirmed state: the accent, because something happened */
.stopper-acts button.done { background: var(--accent); border-color: var(--accent); color: var(--cta-ink); --ico-color: currentColor; }

.hook-boost { margin-top: 1.25rem; }
.hook-boost button {
  color: var(--ink); background: transparent; border: 1px solid var(--ink);
  border-radius: var(--pill); font-family: var(--font-mono); font-size: var(--t-1);
  letter-spacing: .1em; text-transform: uppercase; padding: .55rem 1.1rem;
  cursor: pointer; min-height: var(--touch-min);
}
.hook-upsell { margin-top: 2rem; color: var(--quiet); font-family: var(--font-body); font-size: var(--t-3); max-width: var(--prose); }
.hook-upsell a { color: var(--accent); }
.hook-status { font-family: var(--font-mono); font-size: var(--t-1); color: var(--quiet); }

@media (prefers-reduced-motion: reduce) {
  .hook-go { transition: none; }
  /* The press state itself stays. It is a state, not an animation: with the
     transition gone it snaps, which is what this setting asks for. */
  [data-theme="social"] .clear-btn { transition: none; }
}

/* --- 2026-08-15 additions: the engine's controls and render targets, in the
   skin's own grammar. Spec: 2026-08-15-scroll-desk-reskin-x-posting. --- */

/* The pass renders in the stopper grammar: each post is a stopper card, the
   part label wears the angle mark's treatment. */
[data-theme="social"] .sd-post, [data-theme="social"] .sd-single { border: 1px solid var(--rule); background: var(--paper-deep); padding: 1.1rem 1.2rem; margin: 0 0 1rem; }
[data-theme="social"] .sd-post-no { font-family: var(--font-mono, monospace); font-size: var(--t-1); letter-spacing: .16em; text-transform: uppercase; color: var(--hot); margin: 0 0 .55rem; }
[data-theme="social"] .sd-text { white-space: pre-wrap; overflow-wrap: break-word; color: var(--ink); line-height: 1.55; }
[data-theme="social"] .sd-text:focus { outline: 1px solid var(--accent); outline-offset: 6px; }
[data-theme="social"] .sd-tags { color: var(--ink-soft); margin: .4rem 0 0; }
[data-theme="social"] .sd-actions { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin: 1.2rem 0 0; }
[data-theme="social"] .sd-post-row { margin: .8rem 0 0; }
[data-theme="social"] .sd-reading, [data-theme="social"] .sd-await, [data-theme="social"] .sd-empty { color: var(--quiet); font-style: italic; }
/* The waiting line stands where its replacement will stand. #sdResult is a
   .hook-stoppers and opens 1.5rem below whatever precedes it; this line had
   margin 0, so it sat hard against the connect band above it — measured 0.0px
   between them on the 2026-08-15 preview, which is what Ritu saw — and then
   the page jumped 1.5rem when the post arrived. One value fixes both. */
[data-theme="social"] .sd-await { margin: 1.5rem 0 0; }
[data-theme="social"] .sd-error { color: var(--ink); font-weight: 600; border: 1px solid var(--hot); padding: .7rem .9rem; margin: 1rem 0 0; }
[data-theme="social"] .sd-prov { margin: 1.6rem 0 0; border-top: 1px solid var(--rule); padding-top: 1rem; }
[data-theme="social"] .sd-prov summary { cursor: pointer; color: var(--ink-soft); }
[data-theme="social"] .sd-lane { margin: 1rem 0 0; }
[data-theme="social"] .sd-lane-label { font-family: var(--font-mono, monospace); font-size: var(--t-1); letter-spacing: .16em; text-transform: uppercase; color: var(--quiet); margin: 0 0 .4rem; }
[data-theme="social"] .sd-lane ul { margin: 0; padding-left: 1.1rem; }
[data-theme="social"] .sd-receipt { color: var(--accent); }
[data-theme="social"] .sd-note { color: var(--ink-soft); font-style: italic; margin: 1rem 0 0; }
[data-theme="social"] .sd-hidden { display: none; }

/* ---- THE QUIET CONTROLS. Three buttons arrived on 2026-08-15 carrying a
   border and nothing else, and the render pass measured what that meant: Copy
   this post, Give me another and Connect your X account came out 30.1px tall
   in the browser's own Arial at 13.3px, square, next to a Hook me that is
   47.8px of mono uppercase in a pill. They were the only square, non-mono,
   below-touch-min controls on the page, which is why the connect box read as
   nothing anybody drew. They take the grammar .hook-upload and
   .stopper-acts button already share, so Speak it, Photo, Copy this post,
   Give me another and Connect are now one set: edge border at rest, accent on
   hover, because colour is state and a hover is state. ---- */
[data-theme="social"] .sd-post-copy,
[data-theme="social"] .sd-reroll,
[data-theme="social"] .hook-connect button {
  font-family: var(--font-mono); font-size: var(--t-1); letter-spacing: .1em;
  text-transform: uppercase; color: var(--quiet); background: transparent;
  border: 1px solid var(--edge); border-radius: var(--pill);
  padding: .55rem 1.1rem; cursor: pointer; min-height: var(--touch-min);
}
[data-theme="social"] .sd-post-copy:hover,
[data-theme="social"] .sd-reroll:hover,
[data-theme="social"] .hook-connect button:hover { color: var(--ink); border-color: var(--accent); }
[data-theme="social"] .sd-post-copy:focus-visible,
[data-theme="social"] .sd-reroll:focus-visible,
[data-theme="social"] .hook-connect button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- THE CONNECTION BAND. It was a lone button hanging under the config
   rail, belonging to nothing. It is now the desk's closing row: it hangs off
   .tool-config's bottom hairline and shuts with one of its own, at the width
   of the frame, so it reads as the last band of the desk rather than the first
   thing after it.

   The X mark leads the row and says WHICH account, which is the one thing the
   row had no way to say. It is not in shell/icons.json and must not go there:
   that set is action marks, drawn in one stroke weight, and this is a brand
   glyph that happens to be filled. No words were added — the copy on this
   strip is Ritu's and is still out for his pass.

   Quiet at rest. The mark takes the accent only when the account is linked,
   which is the sheet's first law: something has happened. ---- */
/* One line, deliberately: tests/scroll-desk-skin.test.js reads
   `.hook-connect { display: flex` as a literal to prove the hide below still
   wins. Reformatting this rule breaks that guard. */
[data-theme="social"] .hook-connect { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin: 0; padding: .9rem 0; border-bottom: var(--hairline) solid var(--rule-soft); color: var(--ink-soft); }
[data-theme="social"] .hook-x-mark { width: 1.05rem; height: 1.05rem; flex: none; display: block; color: var(--quiet); }
[data-theme="social"] .hook-connect.is-linked .hook-x-mark { color: var(--accent); }
/* display:flex above sits later than .sd-hidden at equal specificity (the
   .print img trap framework.html documents), so the hide must win back —
   found on the 2026-08-15 render pass, where the strip showed with no API. */
[data-theme="social"] .hook-connect.sd-hidden { display: none; }
[data-theme="social"] .hook-box-row { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; margin-top: .7rem; }

/* The recovered .hook-stoppers rule above puts two children side by side at
   desktop width. This page's #sdResult only ever holds two: the output
   column and the provenance <details>. Provenance belongs BENEATH the
   output, not beside it, so this page overrides back to single-column flow
   without touching the recovered region. */
[data-theme="social"] .hook-stoppers#sdResult { display: block; }
/* The id selector above outweighs .sd-hidden, so the hide must win back at
   the same weight — the second .print-img-trap instance found on the
   2026-08-15 render pass. */
[data-theme="social"] .hook-stoppers#sdResult.sd-hidden { display: none; }

/* The voice's one-liner sits under the select; the menu carries names alone
   (Ritu, 2026-08-15 preview: "All selections should be in one line each"). */
[data-theme="social"] .hook-voice-note { color: var(--quiet); font-style: italic; font-size: var(--t-2); line-height: 1.45; max-width: 22rem; }
/* The VOICE note keeps two lines of room whether it needs them or not. The
   rewritten notes run one line or two depending on the voice and the width,
   and without a floor the Web research cell below jumped every time the menu
   changed. Two is the real ceiling, measured on all eleven notes at 320, 390,
   500, 620, 900, 1100 and 1440: none reached three, none overflowed the rail.
   Scoped to this one note because the research notes are shorter and two of
   the three research options carry none at all. */
[data-theme="social"] #sdVoiceNote { min-height: 2.9em; }

/* ============================================================
   THE SETTINGS DRAWER, 2026-09-15, AND THE DESKTOP DOES NOT HAVE ONE.

   Ritu: "How about having that panel we pushed down as a SETTINGS option, as
   in the editorial tools?" He was speaking of the phone: the panel he means is
   the one his ruling of the same morning pushed below the box. On a desktop
   the rail is the left column of a two-column desk and it reads correctly
   there, so it stays.

   THE PAGE CARRIES ONE MARKUP AND THE SHEET DECIDES. The rail is wrapped in
   .settings-panel. editorial-frame.css, which this page loads, gives that class
   position: fixed and display: none, so left alone the desktop rail would
   vanish. display: contents takes the wrapper's box away entirely and hands
   .tool-panel back to .tool-config's grid as a direct child, which is what it
   was before the wrapper existed.

   The attribute plus the class outranks the shared sheet's single class, and
   this file loads after it, so both ways of winning are covered rather than
   one assumed.
   ============================================================ */
[data-theme="social"] .settings-panel { display: contents; }
/* The drawer's own heading belongs to the drawer. In the desktop rail it would
   be a second title above three labels that already say what they are. */
[data-theme="social"] .settings-panel > h2 { display: none; }
[data-theme="social"] .settings-backdrop { display: none; }
[data-theme="social"] .settings-toggle { display: none; }

/* ============================================================
   THE PHONE LAYER on this sheet (Task 14 fix round 2,
   2026-09-11). The first and only @media (max-width: 699.98px)
   block in this file. 699.98px is --phone-max, the one edge
   every phone rule on this branch reads; the literal is written
   out because a media query cannot read a custom property.
   Above the breakpoint this block is inert and the Scroll Desk
   on a desktop is exactly what it was, which matters here more
   than anywhere else on this branch: HookCraft shipped to
   production on 2026-08-15 and this page is live.
   ============================================================ */
@media (max-width: 699.98px) {
  /* THE HEROES ARE ONE SIZE ACROSS THE APP. Ritu, 2026-09-12, on his phone:
     "the hero 'Stop the scroll' may be larger in size than the rest, or are my
     eyes lying?" They were not. MEASURED across the seven app surfaces at 390:
     five editorial heroes at 18.72px, FrameWork at 21.84, and this one at 40.
     Three sizes where his ruling of 2026-09-06 asks for one: "every tool
     across the project must have a hero of the same size. UNIFORMITY
     PRINCIPLE", and "I mean ONLY the tools. Not the landing pages."

     The size is a ceiling, not a preference: the longest hero that must hold
     one line is ReporterAlly's, which cannot exceed 18.72px at 390 without
     wrapping. So every tool takes the editorial ramp, 17.3 / 18.0 / 18.7 /
     19.8 at 360 / 375 / 390 / 412.

     IT HAD TO BE WRITTEN HERE, and the first attempt was written into
     social-dark.css where it did nothing at all: scroll-desk.html loads
     editorial-frame.css, THIS sheet and icons.css, and not social-dark.css.
     A rule in a sheet a page never loads is not a weak rule, it is no rule. */
  .hook-title { font-size: clamp(var(--t-4), 5.8vw, var(--t-6)); }
  /* THE HERO DOES NOT MOVE. Ritu, 2026-09-13, after seeing the sticky version
     on his phone: "The hero still moves in each of the tools. It should be
     completely static." The reasoning, the 46px and the three consequences of
     fixed are written out once, at the phone block of
     assets/css/editorial-frame.css, which this page also loads and which
     declares both --phone-mast-h and --phone-hero-h.

     Only the title is fixed. .hook-hero holds the title AND the standfirst, and
     a band carrying both would take 135px of a 700px screen; the standfirst
     stays in the flow and scrolls, under the band, like everything else. */
  .hook-title {
    position: fixed;
    top: var(--phone-mast-h);
    left: 0;
    right: 0;
    z-index: 29;
    background: var(--paper);
    padding: 2rem calc((100% - var(--frame)) / 2) var(--s-2);
    line-height: 22px;
    margin: 0;
    /* The height is DECLARED, not left to the type. The Scroll Desk's title
       carries an inline-block highlight on one word, and that box made the line
       taller than the line-height: the band came out 47.7px against the 46 the
       page below had been pushed down by, and the standfirst sat 1.7px too high.
       A band whose height a page depends on cannot be a font metric. */
    box-sizing: border-box;
    height: var(--phone-hero-h);
  }
  .hook-stage { padding-top: calc(var(--phone-hero-h) + var(--s-3)); }
  /* HOOK ME HOLDS THE COLUMN THE BOX IT ACTS ON HOLDS.
     Reported by scripts/phone_balance_check.mjs, the same fault the owner
     named on DeskCopy Pro's Rewrite. Measured at 390: the raw-copy
     textarea and the panel above it hold 24.4..365.6 and Hook me held
     24.4..203.1, 161.23px short. 133.77px short at 360, 181.39px at 412.

     Clear takes the rule too, and that is the point of writing it here
     rather than reaching for .hook-go alone. Clear sits in the same
     .action-row at opacity 0 until there is copy to clear, so no gate
     measures it at page load; left at its own 94.5px it would stand alone
     and short on its own line the moment it appeared, which is the same
     fault again, planted behind the fix for the first one.

     The pill group above them is deliberately NOT stretched. It is a
     segmented control whose three pills measure 247.5px of content, and
     giving its track the full 341px column would leave 70px of empty
     track at the right, which is a worse-looking box than the one this
     round set out to fix. Making the two BUTTONS full width is what puts
     them each on their own line under it, so the row reads as a group of
     shapes over two actions rather than as three things of three widths.

     This rule lives in scroll-desk.css, not in the two sheets this task's
     brief names. .hook-go is declared here and nowhere else, and so is
     every other rule that places it, including the min-width: 11rem this
     one overrides in effect; a .hook-go rule in editorial-frame.css would
     be a class from one page's sheet living in the product's shared one,
     and it would lose on source order besides, since this file loads
     after it. Task 13 touched this same file for this same page for the
     same reason and recorded it the same way. */
  .action-row > .hook-go,
  .action-row > .clear-btn {
    width: 100%;
  }

  /* THE DESK OPENS ON THE BOX, NOT ON ITS SETTINGS.
     Ritu, 2026-09-15, on his phone: "HookCraft opens with the settings panel
     on top."

     MEASURED at 358 on a 650px screen before any of this: the rail ran 275 to
     698 and the box started at 749.5, which is 99.5px below the bottom of the
     screen. Not one pixel of the thing you type into was on the first screen.
     The rail is 423px tall because each of its three cells carries a label, a
     menu and a note.

     IT WAS ANSWERED TWICE IN ONE DAY AND THE SECOND ANSWER IS THE ONE HERE.
     His first ruling, from three rendered screens, was to put the box first and
     leave the rail below it, which was two `order` declarations. He then asked
     for the rail to go behind Settings instead, "as in the editorial tools",
     and chose that from three more. The order rules are gone with it: the rail
     is not in this column at any width now, so there is nothing left to order.
     The screen he approved is still the screen he gets, with one thing on it
     rather than two.

     What follows is that drawer. */
  /* THE WRAPPER IS A DRAWER HERE, and the gear is the way into it.
     The declarations are the shared sheet's own, restored one by one rather
     than re-declared: display: none until .visible, which is exactly what
     editorial-frame.css says and what the rule above this media query turns
     off for the desktop. */
  [data-theme="social"] .settings-panel { display: none; }
  [data-theme="social"] .settings-panel.visible { display: block; }
  [data-theme="social"] .settings-panel > h2 { display: block; }
  [data-theme="social"] .settings-backdrop.visible { display: block; }
  [data-theme="social"] .settings-toggle { display: inline-flex; align-items: center; }

  /* AND THE WAY OUT STAYS IN THE ROW WITH IT.
     editorial-frame.css hides .mast-nav-link on a phone and puts it back only
     for a masthead with no settings button, which on 2026-09-12 meant this desk
     and no other. Adding the gear took the pill away by that rule's own logic,
     and the first render of this build showed a masthead holding nothing but
     the wordmark and a gear.

     THE RULE'S CONDITION IS CROWDING, and its own note says so: the 2026-07-17
     reason is that device font scaling can overflow the compact row. That row
     carries the story control and the theme toggle as well. This one carries
     neither: the story control ships empty here and the theme toggle is hidden
     by this page's own [data-theme="social"] rule. So the row is the wordmark,
     the pill and the gear.

     MEASURED with all three in place, and the numbers are the reason this is
     allowed rather than an assertion that it looks fine. Wordmark to the left
     edge against the last control to the right edge: 16.0 / 16.0 at 320, and
     24.2 / 24.2 at 358, 390 and 412. Exactly equal, not near enough. The pill
     and the gear share one line at every width, the masthead stands at 60px
     throughout, and at 1440 the gear measures 0 wide because the rule above
     this block hides it, so the desktop row is the row it always was.

     It also matters more here than anywhere: this pill is the way off the page
     without scrolling to the foot, and Ritu's complaint of 2026-09-15 was
     precisely about where the way out lands. */
  [data-theme="social"] .masthead-utility .mast-nav-link { display: inline-flex; }

  /* THE ORDER RULES OF THIS MORNING ARE GONE, and they were his ruling, so the
     reason is written down. He chose "box first" from three rendered screens
     at 09:00 and the rail moved below the box. He then asked for the rail to go
     behind Settings instead, which takes it out of the column altogether: there
     is nothing left to order, because .tool-work is the only child in the flow.
     The screen he approved is still the screen he gets, and it now has one
     thing on it rather than two. */

  /* AND THE HOLE THE REORDER PUT ON SHOW. Clear is hidden by visibility rather
     than by display, so that nothing beside it moves when it appears. On a
     phone the rule above this block gives it the full column, so it is alone on
     its own line and there is nothing beside it: the held place is 68px of
     nothing, 44 for the button and 24 for the row gap.

     MEASURED at 358 with the box first: Hook me ends at 740.4, the action row
     ends at 808.4, and the rail starts at 832.4. Ninety-two pixels between the
     last button and the first setting, of which 68 is a button that is not
     there. It has always been 68px; until today it was at the foot of the page,
     below everything, where nobody looked.

     The button comes back the moment there is something to clear, and it pushes
     the rail down as any stacked control does. */
  .action-row > .clear-btn.is-idle { display: none; }
}


/* THE STANDFIRST TO THE PANEL, 32 ON A PHONE. The owner, 2026-09-16, of three
   rendered gaps: "Social option 2", which was 32. It was 40 here and 38.8 on
   FrameWork, 1.2px apart and the same gap to the eye; both are 32 now.

   SCOPED TO THIS DESK ON PURPOSE. `.tool-config { margin: var(--s-5) 0 0 }` in
   editorial-frame.css is shared with every editorial tool, and there the
   heading's own margin stacks on top of it and draws 56, not 40. Changing the
   shared rule would have moved six pages he has not looked at.

   BOTH SIDES, because these margins collapse: the hero's own bottom margin is
   32.296px and the larger of the pair is what paints. Dropping only the panel
   would have left 32.3 and looked like a miss. */
@media (max-width: 430px) {
  .hook-hero { margin-bottom: calc(var(--s-1) * 8); }
  .tool-config { margin-top: calc(var(--s-1) * 8); }
}

/* ── THE ACTION IS REACHABLE WITHOUT A FINGER ───────────────────────────────
   Ritu, 2026-09-20, with a photograph of his phone: "At first glance, Hook Me
   is only partially visible." And the rule underneath it: "In every tool,
   without using one's fingers, you should be able to see the full thing, talk
   to the desk, not halfway."

   MEASURED at 358 on a 620px screen, which is what his installed app gives
   once Android's status and navigation bars are taken off a 412px phone
   laying out near 358: this row ran 610..732, so Hook me sat 112px below the
   fold and the shape switch was off screen too. The page does not scroll the
   masthead away, so nothing brought it up.

   WHY THIS IS NOT A PATCH, and the distinction matters because three patches
   were offered first and he refused them, correctly, as "stopgap solutions
   which will introduce new problems". Every other desk in this product
   already pins its action row: editorial-frame.css does it at
   body.has-phone-tabs .action-bar and .action-row, at bottom: 62px to clear
   the tab bar. This desk is the only one that never loaded phone-places.js,
   so it never got the class, so it never got the rule. It is the outlier
   joining the pattern, not a new idea. bottom: 0 rather than 62 because this
   page carries no tab bar yet; when it gets its three places the offset
   becomes the shared one.

   SIZE: 122px, against FieldReportage's 129 and DeskCopy Pro's 77. Within
   what this product already asks of a phone screen.

   THE PADDING IS LOAD-BEARING. Without it the bar covers the foot of the
   output, which is the exact defect the 2026-09-20 audit measured on
   DeskCopy Pro: an error "in a box that the pinned action bar half covers".
   Fixing one page by importing another page's bug is not a fix. */
@media (max-width: 700px) {
  .action-row {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 39;
    margin: 0;
    padding: var(--s-2) var(--s-3) calc(var(--s-2) + env(safe-area-inset-bottom));
    background: var(--paper);
    border-top: var(--hairline) solid var(--rule);
  }
  /* The tallest the bar gets, plus its own padding, so the last thing on the
     page always clears it. Measured, not guessed: 122 + 8 + 8 + 16 = 154. */
  body:has(.action-row) { padding-bottom: 154px; }
}
