/* HouseChalk layout — the responsive rules, and why they are container queries.
 *
 * VIEWPORT MEDIA QUERIES ARE THE WRONG TOOL HERE, and that is the trap this
 * file exists to avoid. A `@media (min-width: 840px)` matches the PAGE a
 * component is drawn on, not the frame the component sits in — so a 390px phone
 * frame previewed on a desktop page would take the desktop layout. Everything
 * below is relative to the component's OWN container.
 *
 * MOBILE FIRST IS NOT A SLOGAN HERE. Every rule's unqualified value is the
 * phone value; a container query only ever adds. A component that never gets a
 * container is a phone component, correctly.
 *
 * THE FOUR-TIER LADDER. Named once, from the source's own measurements of the
 * room grid, and reused rather than re-derived:
 *
 *     phone    < 560px    one column of content, two-up rooms
 *     wide     >= 560px   the phone's layout with more air
 *     tablet   >= 840px   side by side becomes available
 *     desk     >= 1120px  the rail and the pane
 */
:root{
  --bp-wide:560px;
  --bp-tablet:840px;
  --bp-desk:1120px;
  --canvas-max:1120px;   /* the desktop content container, inside a 1160px frame */
  --rail-width:280px;    /* the desktop navigation rail */
}

/* Every HouseChalk surface names itself as a container so the rules below have
   something to measure. `inline-size` and not `size`: these components are
   height-driven by their content and a size container would break that. */
/* A QUERY CONTAINER CANNOT STYLE ITSELF — a container query resolves against the
   nearest ANCESTOR container, never the element that declares one. So the FRAME
   is the container and the scroll inside it is what gets styled; naming the
   scroll as its own container would only ever fire on a nested scroll, which
   this system forbids anyway (a phone is one screen). */
[data-hc-frame],[data-hc-canvas],[data-hc-scroll],[data-hc-rooms],[data-hc-dock],[data-hc-pane]{container-type:inline-size}
[data-hc-frame]{container-name:hcframe}
[data-hc-canvas]{container-name:hccanvas}
/* BOTH NAMES IN ONE DECLARATION. container-name is not additive across rules —
   a second rule replaces the first — so a canvas that is also a frame has to say
   so once. */
[data-hc-canvas][data-hc-frame]{container-name:hccanvas hcframe}
[data-hc-scroll]{container-name:hcscroll}
[data-hc-dock]{container-name:hcdock}

/* ---- The room grid --------------------------------------------------------
   `minmax(min(240px, 47%), 1fr)` reads as: a room wants 240px, but never more
   than about half the container — which is what pins the phone to two columns.
   The percentage is of the grid's own width, so it follows the container and not
   the window. Measured: 346px -> 2 @ 165 · 560 -> 2 @ 272 · 800 -> 3 @ 256 ·
   1040 -> 4 @ 248 · 1280 -> 5 @ 243.

   TWO-UP ON A PHONE IS A DELIBERATE COMPROMISE, not the ideal. A room card
   wants 240px and gets 165. It stays two-up because the room grid is the
   binder's contents page: seeing the whole house at once is the reassurance the
   first run is built on. One-up would show a room and a half per screen and turn
   the house into a queue. */
[data-hc-rooms]{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(min(240px,47%),1fr))}
@container hcscroll (min-width:560px){[data-hc-rooms]{gap:16px}}
@container hccanvas (min-width:840px){[data-hc-rooms]{gap:16px}}

/* ---- The scroll -----------------------------------------------------------
   THE GUTTER IS A CUSTOM PROPERTY, NOT A PADDING RULE, and that is the only way
   it can work. Scroll sets its padding inline (inline styles beat any
   stylesheet), so the responsive layer cannot set padding-inline directly — it
   sets --hc-gutter, which the inline padding reads through var(). The query
   hangs off the FRAME, which is the scroll's ancestor container.

   The gutter opens up as the frame does; the 22px block rhythm does not, because
   the gap between two blocks is a relationship rather than a proportion. */
[data-hc-scroll]{--hc-gutter:24px;-webkit-overflow-scrolling:touch;scrollbar-width:thin;overscroll-behavior-y:contain}
@container hcframe (min-width:560px){[data-hc-scroll]{--hc-gutter:32px}}
@container hcframe (min-width:840px){[data-hc-scroll]{--hc-gutter:40px}}
[data-hc-scroll]::-webkit-scrollbar{width:6px}
[data-hc-scroll]::-webkit-scrollbar-thumb{background:var(--rail-ink);border-radius:999px}

/* ---- The rail ------------------------------------------------------------
   A carousel is the ONE component allowed to break the scroll's gutter: the
   next card peeking past the edge is what says the row scrolls, and a rail that
   stops at the gutter reads as a clipped grid. It bleeds by --hc-gutter and
   pays it back as padding, so the first card still lines up with everything
   above it. The scrollbar is hidden because a peeking card already says it.
   NO SCROLLBAR RULE CAN BE INLINE, which is why the rail lives here. */
[data-hc-rail]{scrollbar-width:none;-ms-overflow-style:none}
[data-hc-rail]::-webkit-scrollbar{display:none}

/* ---- The desktop canvas ---------------------------------------------------
   Not a phone bezel and not pretending to be a browser: just the page area.
   1160 wide with a 20px dock inset gives the 1120 container the nav menu's wide
   metrics are derived from.

   NO OVERFLOW RULE HERE. AppCanvas sets overflow: hidden inline (which would beat
   a stylesheet rule anyway) and gives the rail and the content column a scroll
   each, so the desk bar stays put. */
[data-hc-canvas] [data-hc-pane]{width:min(100%,var(--canvas-max));margin-inline:auto}

/* Side by side only becomes available at tablet width, and it is opt-in per
   region rather than a page-wide switch — one content river is still the
   posture, and two columns of equally weighted tiles is the thing this product
   refuses. */
/* STRETCH, AND THAT IS DELIBERATE. Cards of equal height side by side read as
   one row; cards of different heights read as a mistake, and the ragged gap
   below the shorter one is worse than any emptiness inside it. So a cell fills
   its row.

   WHICH MOVES THE PROBLEM TO WHAT YOU PAIR, WHICH IS WHERE IT BELONGS. A cell
   holds a COLUMN, not necessarily a single card: pair one tall card with a
   STACK of two or three short ones and the heights resolve on their own. That
   is the bento arrangement, and it is authored rather than computed —
   `data-hc-stack` is the column you put in a cell.

   The rule that follows: never pair a one-figure card with a chart. Give the
   one-figure card siblings until the two columns weigh the same. */
[data-hc-cols]{display:grid;gap:24px;align-items:stretch}
/* A cell that holds several cards instead of one. Cards inside it size to their
   own content — the STACK fills the row, not each card in it. */
[data-hc-stack]{display:grid;gap:24px;align-content:start}
@container hccanvas (min-width:840px){[data-hc-cols]{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container hccanvas (min-width:1120px){[data-hc-cols="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ---- The dock -------------------------------------------------------------
   The nav menu takes its metrics from the CONTAINER, so a phone frame resolves
   phone metrics even on a desktop page. Four tiles narrow, eight wide. */
[data-hc-tiles]{display:grid;gap:8px;grid-template-columns:repeat(4,minmax(0,1fr))}
@container hcdock (min-width:640px){[data-hc-tiles]{grid-template-columns:repeat(8,minmax(0,1fr))}}

/* ---- The sheet -----------------------------------------------------------
   BOTTOM ON A PHONE, SIDE ON A DESKTOP, and the component does not know which.
   A phone sheet rises from the bottom edge because that is where the thumb is;
   a bottom sheet on a 1160px canvas is a letterbox, so past the tablet rung it
   comes in from the right instead. The query hangs off the FRAME, so a phone
   drawn on a desktop page still gets the phone treatment.

   IT CAPS ITS OWN HEIGHT AT 88%. A sheet that can reach the top edge is a
   screen wearing a scrim — the sliver of the surface behind it is what says
   the reader has not gone anywhere. */
[data-hc-sheet]{margin-top:auto;width:100%;max-height:88%;border-radius:var(--r-card) var(--r-card) 0 0}
@container hcframe (min-width:840px){
  [data-hc-sheet]{margin-top:0;margin-left:auto;width:min(480px,86%);max-height:100%;height:100%;border-radius:var(--r-card) 0 0 var(--r-card)}
}

/* ---- Touch ----------------------------------------------------------------
   44px MINIMUM, ALWAYS, and the visual size is not the target size. A 38px icon
   button is the right drawing and the wrong hit area, so the target is grown
   with a pseudo-element rather than by inflating the button. */
[data-hc-touch]{position:relative}
[data-hc-touch]::after{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:max(100%,var(--touch-min));height:max(100%,var(--touch-min))}
@media (pointer:fine){[data-hc-touch]::after{display:none}}

/* ---- Real devices ---------------------------------------------------------
   Only applies where a HouseChalk surface IS the viewport. Inside a drawn phone
   frame the insets resolve to zero, so one rule serves both. */
[data-hc-safe]{padding-bottom:calc(var(--dock-reserve) + env(safe-area-inset-bottom,0px))}
[data-hc-safe-top]{padding-top:calc(48px + env(safe-area-inset-top,0px))}
