/* ==========================================================================
   Home Church, screen layout
   Only the pieces that are specific to one screen. Anything reused belongs
   in components.css.
   ========================================================================== */

/* --------------------------------------------------------------- the mark */

.hc-mark {
  display: block;
  width: 34px;
  height: auto;
}

.hc-avatar__icon {
  width: 22px;
  height: 22px;
  stroke: var(--hc-accent-deep);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ==========================================================================
   Home
   ========================================================================== */

.hc-home__greeting {
  margin-top: var(--hc-space-sm);
  margin-bottom: var(--hc-space-lg);
  /* Matches the section headers' treatment. Scoped here rather than on
     .hc-display-l itself, which the Guide reader's sermon titles also use
     and are meant to stay the light reading serif. */
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: calc(28px * var(--hc-text-scale));
  line-height: 1.15;
  letter-spacing: -0.01em;
}

/* ------------------------------------------------------ the featured video

   The frame between the greeting and Announcements. It carries no heading, no
   eyebrow and no caption, so the only thing that separates it from the two
   blocks around it is air, and it gets the same lg gap the greeting already
   puts under itself. See js/featured-video.js. */

.hc-featured {
  position: relative;
  margin-bottom: var(--hc-space-lg);
}

.hc-featured__frame {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
  /* The same cream every other piece of missing art in the app shows while
     it loads, so a slow embed is a warm rectangle rather than a black one. */
  background: var(--hc-cream);
}

/* A Short, filmed on a phone held upright. Capped the way the carousel's tall
   slides are, for the same reason: one video should not take the whole screen
   and push Sunday off the bottom of it. */
.hc-featured--tall .hc-featured__frame {
  aspect-ratio: 9 / 16;
  max-height: 62vh;
}

.hc-featured__player {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Top right, which is the one corner of a YouTube embed with nothing of its
   own in it: the controls run along the bottom and the title sits top left. */
.hc-featured__sound {
  position: absolute;
  top: var(--hc-space-md);
  right: var(--hc-space-md);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--hc-radius-pill);
  /* Its own ink rather than a token, both appearances. This sits on a
     photograph rather than on the page, so it has to hold against whatever
     the video is showing rather than against the paper behind it. */
  background: rgba(17, 17, 17, 0.62);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
  backdrop-filter: blur(8px) saturate(120%);
  color: #FFFCF7;
  font-family: var(--hc-sans);
  font-size: calc(13px * var(--hc-text-scale));
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* The 44pt target the rest of the app keeps, without a 44px pill sitting on
   the video. The button is 36 high and the finger's half of it reaches past
   the edges, which is what ::before is for everywhere else in this app. */
.hc-featured__sound::before {
  content: '';
  position: absolute;
  inset: -4px;
}

.hc-featured__sound:active { opacity: 0.85; }

.hc-featured__soundicon {
  width: 17px;
  height: 17px;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.hc-gathering__when { margin-top: 6px; }

.hc-gathering__times {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm) var(--hc-space-base);
  margin-top: var(--hc-space-md);
  list-style: none;
}

.hc-gathering__time {
  color: var(--hc-ink);
  font-variant-numeric: tabular-nums;
}

.hc-gathering__time + .hc-gathering__time {
  padding-left: var(--hc-space-base);
  border-left: var(--hc-hairline) solid var(--hc-rule);
}

.hc-gathering__address { margin-top: var(--hc-space-md); }
.hc-gathering__action { margin-top: var(--hc-space-base); }

.hc-guide-card__title { margin-top: 6px; }

/* The week's guide with its series art beside it. Only drawn when the series
   has art, so the words below fall straight back to the stacked card this has
   always been when it does not. The square leads, because the picture is what
   is recognised from across a room and the type is what is read up close. */
.hc-guide-card__lead {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-base);
}

.hc-guide-card__thumb {
  flex: 0 0 64px;
  width: 64px;
  display: block;
}

.hc-guide-card__words {
  flex: 1 1 auto;
  min-width: 0;
  display: block;
}

.hc-guide-card__cue {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--hc-space-base);
  color: var(--hc-accent-deep);
  font-weight: 600;
}

.hc-guide-card__chev {
  width: 14px; height: 14px;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* No top margin of its own any more. Every block on Home now sits under a
   section header, and `.hc-section-header + *` in components.css owns the gap
   down to what the header names. A second margin here, on top of that one,
   would read as a break in the column rather than a heading and its block. */

/* A <span> now rather than a <p>, because the card is a button and a
   paragraph inside one is invalid markup. The margins stay the same and
   display:block is what a span needs to keep them. */
.hc-banner__title { display: block; margin-top: 6px; margin-bottom: 4px; }

.hc-plan {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--hc-space-base) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

.hc-plan__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hc-space-md);
  margin-bottom: var(--hc-space-md);
}

.hc-plan__title { flex: 1 1 auto; min-width: 0; }
.hc-plan__reading { margin-top: var(--hc-space-md); }

/* ==========================================================================
   Listen
   ========================================================================== */

.hc-latest { margin-top: var(--hc-space-lg); }

.hc-latest__media {
  display: block;
  width: 100%;
  padding: 0;
}

.hc-latest__eyebrow { display: block; margin-top: var(--hc-space-base); }
.hc-latest__title { margin-top: 6px; }
.hc-latest__meta { margin-top: var(--hc-space-sm); }
.hc-latest__desc { margin-top: var(--hc-space-md); }
.hc-latest__action { margin-top: var(--hc-space-base); }

/* --- The series picker -----------------------------------------------------
   The rail is the carousel from Home, unchanged, so everything here is about
   what sits under it: the caption that names whichever series you have landed
   on, and that series' messages below it. The carousel's own bottom margin is
   dropped, because the caption belongs to the tile above it and a screenful of
   air between them would say they were two separate blocks.
   -------------------------------------------------------------------------- */

.hc-series-picker { margin-top: var(--hc-space-base); }
.hc-series-picker .hc-carousel { margin-bottom: 0; }

/* The tiles are artwork and nothing else. What names them is the caption, so
   the slide's only child that takes space is the cover itself. Real series art
   sits on top of that cover rather than replacing it, which is what makes a
   photograph that never arrives fall back to the drawn tile underneath, and
   that layering is `.hc-cover__art` in components.css: it is the same tile
   here, on the episode rows and on Home. */
.hc-series-slide .hc-cover { width: 100%; }

.hc-series-meta { margin-top: var(--hc-space-md); }
.hc-series-meta__kicker { display: block; }
.hc-series-meta__title { margin-top: 4px; }
.hc-series-meta__sub { margin-top: var(--hc-space-sm); }
.hc-series-meta__count { margin-top: 6px; }

.hc-series-list { margin-top: var(--hc-space-base); }

/* The episode list closes on a hairline of its own and the Archive opens with
   one. Two rules a thumb's width apart read as a seam rather than as the break
   between two blocks, so the one underneath goes. */
.hc-series-picker + .hc-section { border-top: 0; }

.hc-archive-group { margin-top: var(--hc-space-lg); }
.hc-archive-group__label { display: block; margin-bottom: var(--hc-space-sm); }

/* The archive lives inside a collapsible panel, and the panel already opens a
   gap of its own above the first thing in it. */
.hc-section__panel > div > .hc-archive-group:first-child { margin-top: 0; }

.hc-sermon {
  padding: var(--hc-space-base) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-sermon:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }

.hc-sermon__main {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-base);
  width: 100%;
  text-align: left;
  min-height: var(--hc-tap-min);
}

/* Square, the shape podcast artwork actually comes in. */
.hc-sermon__thumb {
  flex: 0 0 76px;
  width: 76px;
  display: block;
}

.hc-sermon__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hc-sermon__chevron {
  /* Leads the row rather than ending it. Drawn last in the markup, because
     the toggle's tap and its aria-expanded both read the button and not the
     order of what is painted inside it, so `order` moves the mark without
     touching either. The right of this row is the month rail's, and a chevron
     against a ruler reads as one of its notches. */
  order: -1;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  color: var(--hc-mid);
  transition: transform var(--hc-dur-fast) var(--hc-ease);
}

.hc-sermon__main[aria-expanded="true"] .hc-sermon__chevron { transform: rotate(180deg); }

/* Episode notes, opened in place under the row they belong to. */
.hc-episode {
  overflow: hidden;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--hc-dur-base) var(--hc-ease);
}

.hc-episode[data-open="true"] { grid-template-rows: 1fr; }

.hc-episode__inner { min-height: 0; }

.hc-episode[data-open="true"] .hc-episode__inner { padding-top: var(--hc-space-md); }

.hc-episode__para + .hc-episode__para,
.hc-latest__desc .hc-episode__para + .hc-episode__para {
  margin-top: var(--hc-space-md);
}

.hc-episode__action { margin-top: var(--hc-space-base); }

.hc-show-card__action { margin-top: var(--hc-space-base); }

/* ==========================================================================
   Guide, index
   ========================================================================== */

.hc-guide-intro {
  margin-top: var(--hc-space-base);
  color: var(--hc-mid);
}

.hc-guide-list { margin-top: var(--hc-space-sm); }

.hc-guide-row {
  display: flex;
  align-items: center;
  gap: var(--hc-space-base);
  width: 100%;
  text-align: left;
  min-height: 72px;
  padding: var(--hc-space-base) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
  transition: opacity var(--hc-dur-fast) var(--hc-ease);
}

.hc-guide-row:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }
.hc-guide-row:active { opacity: 0.6; }

/* The series' art, when the series has any. Smaller than the square on a
   Listen row: that one is the episode's artwork and leads the row, this one
   is the shelf the guide came off and sits beside three lines of type it must
   not out-shout. */
.hc-guide-row__thumb {
  flex: 0 0 56px;
  width: 56px;
  display: block;
}

.hc-guide-row__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hc-guide-row__title {
  font-family: var(--hc-serif);
  font-weight: 500;          /* was 300, see the note in base.css */
  font-size: calc(23px * var(--hc-text-scale));
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--hc-ink);
}

/* ==========================================================================
   Guide, reader
   ========================================================================== */

.hc-reader__head { padding-top: var(--hc-space-sm); }

.hc-reader__title { margin-top: var(--hc-space-sm); }

.hc-reader__subtitle {
  margin-top: var(--hc-space-sm);
  color: var(--hc-mid);
  font-style: italic;
}

.hc-reader__rule {
  width: 22%;
  min-width: 56px;
  height: 0.75px;
  background: var(--hc-accent);
  margin: var(--hc-space-base) 0 var(--hc-space-md);
}

.hc-reader__meta { font-variant-numeric: tabular-nums; }

/* Stacks, because there can be two, and they are full width buttons. */
.hc-reader__actions {
  margin-top: var(--hc-space-base);
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-md);
}

.hc-reader__leader {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-base);
  border: var(--hc-hairline) solid var(--hc-rule);
  border-radius: var(--hc-radius-lg);
}

.hc-reader__leader-note {
  margin-top: var(--hc-space-md);
  text-align: center;
}

/* Discussion questions */

.hc-coverage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-base);
  padding-bottom: var(--hc-space-sm);
}

.hc-coverage .hc-caption { flex: 1 1 auto; }

.hc-qgroup { margin-top: var(--hc-space-lg); }

.hc-qgroup__label { display: block; margin-bottom: var(--hc-space-sm); }

.hc-qgroup .hc-check:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }

/* The three movements, inside the full summary */

.hc-anchors {
  margin-top: var(--hc-space-xl);
  padding-top: var(--hc-space-lg);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-anchors__label { display: block; margin-bottom: var(--hc-space-base); }

.hc-anchors__title {
  font-family: var(--hc-serif);
  font-weight: 400;
  font-size: calc(20px * var(--hc-text-scale));
  line-height: 1.3;
  color: var(--hc-ink);
}

.hc-anchors__body { margin-top: 6px; color: var(--hc-mid); }

/* Self reflection */

.hc-reflection__note {
  margin-bottom: var(--hc-space-lg);
  font-style: italic;
}

/* Scripture */

.hc-scripture-list .hc-row { align-items: flex-start; }
.hc-scripture-list .hc-row .hc-row__chevron { margin-top: 4px; }

/* Closing */

.hc-closing {
  margin-top: var(--hc-space-xl);
  padding: 0 var(--hc-space-base);
  text-align: center;
}

.hc-closing__text { color: var(--hc-ink); }

.hc-closing__ref {
  margin-top: var(--hc-space-md);
  font-family: var(--hc-sans);
  font-weight: 600;
  font-size: var(--hc-eyebrow);
  line-height: var(--hc-eyebrow-line);
  letter-spacing: var(--hc-track-eyebrow);
  text-transform: uppercase;
  color: var(--hc-accent-deep);
}

/* ==========================================================================
   Presentation mode, leader only
   ========================================================================== */

.hc-present {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  padding: calc(env(safe-area-inset-top) + var(--hc-space-lg))
           var(--hc-screen-pad)
           calc(env(safe-area-inset-bottom) + var(--hc-space-lg));
  background: var(--hc-paper);
}

.hc-present__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hc-space-base);
  padding-bottom: var(--hc-space-md);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

.hc-present__count { font-variant-numeric: tabular-nums; }

.hc-present__body {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  padding: var(--hc-space-xl) 0;
}

.hc-present__question {
  font-family: var(--hc-serif);
  font-weight: 500;          /* was 300, see the note in base.css */
  font-size: calc(30px * var(--hc-text-scale));
  line-height: 1.28;
  letter-spacing: -0.015em;
  color: var(--hc-ink);
}

.hc-present__foot { flex: 0 0 auto; }

.hc-present__check {
  border-top: var(--hc-hairline) solid var(--hc-rule);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
  margin-bottom: var(--hc-space-base);
}

.hc-present__nav {
  display: flex;
  gap: var(--hc-space-md);
}

.hc-present__arrow {
  flex: 1 1 0;
  min-width: 0;
}

.hc-present__arrow[disabled] {
  opacity: 0.35;
  pointer-events: none;
}

.hc-present__arrow .hc-btn__icon {
  width: 22px;
  height: 22px;
}

.hc-present__exit {
  display: flex;
  width: 100%;
  margin-top: var(--hc-space-md);
}

/* ==========================================================================
   Connect
   ========================================================================== */

.hc-filters { margin-bottom: var(--hc-space-base); }

.hc-filters__label {
  display: block;
  margin: var(--hc-space-base) 0 var(--hc-space-sm);
}

.hc-filters__label:first-child { margin-top: 0; }

.hc-group-list { margin-top: var(--hc-space-base); }

.hc-group__blurb { margin-top: var(--hc-space-md); color: var(--hc-mid); }

.hc-group__status {
  margin-top: var(--hc-space-md);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.hc-group__status[data-open="true"] { color: var(--hc-success); }
.hc-group__status[data-open="false"] { color: var(--hc-mid); }

.hc-mygroup__next { margin-top: var(--hc-space-md); }

/* Between group seasons, and now also in the week they open. One card, one
   paragraph, no filter strip standing over an empty list. */
.hc-group__off-season { color: var(--hc-ink); }

/* The season's flyer, above that paragraph.

   NO FRAME AND NO CROP, which is the one thing this rule is for and the one
   way it differs from every other picture in the app. The slides on Home sit
   in a frame of a chosen shape and fill it with object-fit: cover, because a
   photograph of a room has no edges that matter. A flyer does: the date is
   usually printed along the bottom of it and the crop that makes it fit a 4:3
   frame is the crop that cuts the date off. So the height is the height the
   picture is, whatever that turns out to be — a square for Instagram, a
   portrait for a poster, a wide banner for a header — and the shape adapts
   to the art instead of the art being cut to the shape.

   The cap is the other half of that bargain. A tall poster at full width
   would push the paragraph explaining it off the bottom of the phone, so it
   stops at 62vh, the same ceiling the portrait slides on Home use. At the cap
   the picture scales down whole rather than losing its edges.

   Cream underneath for the moment before it arrives and for good if it never
   does, matching every other piece of missing art in the app. */
.hc-group__flyer {
  display: block;
  width: 100%;
  height: auto;
  max-height: 62vh;
  object-fit: contain;
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
  margin-bottom: var(--hc-space-md);
}

/* The way into a group, at the foot of that card and centred.

   ALWAYS LAST AND ALWAYS THERE, which is the whole of this rule. A card that
   is a flyer, a paragraph and an action reads in that order, and the action
   does not move when the paragraph gets longer or the season changes the words
   above it: somebody who joined a group last spring should find the button in
   the same place this autumn.

   Centred rather than stretched, and capped, because a button the full width
   of a phone reads as a bar rather than as a thing to tap — and on a tablet it
   would be a hundred characters of tap target for two words. The cap is a
   comfortable thumb's width and the auto margins do the centring.

   Not .hc-group__join: that name belongs to the joining flow on the Group tab,
   further down this file. Two unrelated screens sharing a class is how one of
   them changes on a Tuesday for no reason anybody can find. */
.hc-group__cta {
  margin-top: var(--hc-space-lg);
  text-align: center;
}

.hc-group__cta .hc-btn {
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
}

/* --- Serve teams ---------------------------------------------------------
   Each team is a collapsible now rather than a one tap interest button, so
   reading about one costs nothing and commits to nothing. */

.hc-serve-list { margin-top: var(--hc-space-sm); }

.hc-serve__commitment { margin-bottom: var(--hc-space-xs); }
.hc-serve__blurb { color: var(--hc-mid); }

/* A background check or a training process. Italic and set apart, the way the
   church's own site prints it, so it reads as a condition rather than as one
   more line of the description. */
.hc-serve__requirement {
  margin-top: var(--hc-space-md);
  font-style: italic;
  color: var(--hc-accent-deep);
}

/* The one signup every team funnels through, sitting under all of them. */
.hc-serve__signup-copy {
  margin-top: var(--hc-space-base);
  color: var(--hc-ink);
}

.hc-serve__signup-action { margin-top: var(--hc-space-lg); }

.hc-serve__signup-note,
.hc-step__note {
  margin-top: var(--hc-space-sm);
  text-align: center;
}

.hc-event-list { margin-top: var(--hc-space-sm); }

.hc-event {
  padding: var(--hc-space-base) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-event:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }

.hc-event .hc-row__title { margin-top: 4px; }
.hc-event__blurb { margin-top: var(--hc-space-sm); color: var(--hc-mid); }

/* Add to calendar and Get notified, side by side under an event.

   A row rather than a stack, because they are two answers to one question and
   a stack reads as a list of steps. It wraps, and the wrap is the point: the
   second one grows a date into its label the moment a reminder is set
   ("Reminding you Sep 11, 6:30 PM"), and at the largest text size that is
   wider than a phone. Two lines is the right failure. A truncated reminder is
   not. */
.hc-event__action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--hc-space-lg);
  margin-top: var(--hc-space-md);
}

/* The offline line under the guide index intro. Icon and text on one
   baseline, quiet enough not to compete with the guides themselves. */
.hc-guide-intro__offline {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-md);
}

.hc-guide-intro__icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  stroke: var(--hc-accent-deep);
}

.hc-step__blurb { color: var(--hc-mid); }

/* A next step with a destination gets a button. One without renders as the
   description alone, which is why this is a separate rule and not padding on
   the blurb. */
.hc-step__action { margin-top: var(--hc-space-lg); }

.hc-form .hc-field + .hc-field { margin-top: var(--hc-space-base); }
.hc-form .hc-btn { margin-top: var(--hc-space-lg); }

/* --- the contact form ------------------------------------------------------
   The first thing on Connect. Nothing here is a new look: the fields are the
   app's own .hc-field and .hc-input, and what these rules do is space them and
   put the honeypot out of reach.
   ------------------------------------------------------------------------ */

.hc-contact__blurb { color: var(--hc-mid); }

.hc-contact__form { margin-top: var(--hc-space-lg); }

.hc-contact__note {
  margin-top: var(--hc-space-md);
  color: var(--hc-mid);
}

.hc-contact__error {
  margin: var(--hc-space-md) 0 0;
  font-size: var(--hc-caption);
  color: var(--hc-error);
}

.hc-contact__actions,
.hc-contact__again { margin-top: var(--hc-space-lg); }

.hc-contact__thanks { margin-top: var(--hc-space-sm); }

/* The honeypot. Off screen rather than display:none, which is the version
   that does not work: a bot worth defending against skips a field the CSS has
   hidden and fills one it has not. Absolutely positioned out of the layout,
   so it costs no space, takes no tab stop (tabindex="-1" on the input), and is
   already aria-hidden in the markup. A person never meets it. */
.hc-contact__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   Give
   ========================================================================== */

.hc-give__line {
  margin-top: var(--hc-space-lg);
  font-size: calc(19px * var(--hc-text-scale));
  line-height: 1.55;
}

.hc-give__action { margin-top: var(--hc-space-xxl); }

.hc-give__note {
  margin-top: var(--hc-space-md);
  text-align: center;
}

/* ==========================================================================
   Services

   NO CARDS ON THIS SCREEN, AND THAT IS THE DESIGN. The two facts on it are a
   time and an address, which is two labelled lines in one column of prose,
   not two objects. A cream box around each would spend a border, a fill and a
   radius saying "these are separate things to look at" about a page whose
   whole job is to be read straight down and left. The eyebrow over each block
   and the hairline above it do the work, which is the move the section header
   at the top of the screen already makes twice.
   ========================================================================== */

.hc-ww__lede {
  margin-top: var(--hc-space-lg);
  font-size: calc(19px * var(--hc-text-scale));
  line-height: 1.55;
}

/* Bold on the website, bold here. It is the line the paragraph above it is
   building to, and the one somebody who reads nothing else should read. */
.hc-ww__welcome {
  margin-top: var(--hc-space-base);
  font-weight: 700;
}

.hc-ww__block {
  display: block;
  margin-top: var(--hc-space-xl);
  padding-top: var(--hc-space-lg);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-ww__when,
.hc-ww__where { margin-top: 6px; }

/* Laid out exactly like the times on Home's gathering card, down to the
   hairline between them, because they are the same three times: a person who
   has seen one and then the other should not have to check that they agree. */
.hc-ww__times {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm) var(--hc-space-base);
  margin-top: var(--hc-space-md);
  list-style: none;
}

.hc-ww__time {
  color: var(--hc-ink);
  font-family: var(--hc-sans);
  font-weight: 600;
  font-size: calc(var(--hc-body-sans) * var(--hc-text-scale));
  font-variant-numeric: tabular-nums;
}

.hc-ww__time + .hc-ww__time {
  padding-left: var(--hc-space-base);
  border-left: var(--hc-hairline) solid var(--hc-rule);
}

.hc-ww__town { margin-top: var(--hc-space-xs); color: var(--hc-mid); }
.hc-ww__action { margin-top: var(--hc-space-lg); }

/* Photographs off the church's own Instagram, in a collage that closes.

   EVERY CELL IS FILLED, WHICH IS THE WHOLE FIX. This grid used to hold three
   frames in a two by three, which left the top left corner empty: a notch out
   of the block that read as a picture that had failed to load rather than as
   a decision. Both arrangements below cover their grid completely, so the
   photographs together are one rectangle with a straight edge on all four
   sides, whatever shapes the pictures inside them happen to be.

   FIVE, OR FOUR. Five is a three by three pinwheel: a tall one top left, a
   wide one across from it, a square in the middle, a tall one bottom right
   and a wide one closing the bottom left, so no two frames of the same shape
   sit next to each other. Four is the two by three the screen can still fill
   when the sync has only mirrored four posts. js/screens/whenwhere.js picks
   between them and draws neither below four.

   Explicit rows rather than aspect-ratio on the frames, so pictures of
   different shapes cannot push the grid around between one sync and the
   next. */
.hc-ww__photos {
  margin-top: var(--hc-space-xxl);
  display: grid;
  gap: var(--hc-space-sm);
}

.hc-ww__frame {
  overflow: hidden;
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
}

/* Five, the ordinary case: the sync keeps nine posts. */
.hc-ww__photos--5 {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 84px);
}

.hc-ww__photos--5 .hc-ww__frame--1 { grid-column: 1; grid-row: 1 / span 2; }
.hc-ww__photos--5 .hc-ww__frame--2 { grid-column: 2 / span 2; grid-row: 1; }
.hc-ww__photos--5 .hc-ww__frame--3 { grid-column: 2; grid-row: 2; }
.hc-ww__photos--5 .hc-ww__frame--4 { grid-column: 3; grid-row: 2 / span 2; }
.hc-ww__photos--5 .hc-ww__frame--5 { grid-column: 1 / span 2; grid-row: 3; }

/* Four: the same idea one column narrower, a tall frame in each column with a
   shorter one squared off above and below it. */
.hc-ww__photos--4 {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, 84px);
}

.hc-ww__photos--4 .hc-ww__frame--1 { grid-column: 1; grid-row: 1; }
.hc-ww__photos--4 .hc-ww__frame--2 { grid-column: 1; grid-row: 2 / span 2; }
.hc-ww__photos--4 .hc-ww__frame--3 { grid-column: 2; grid-row: 1 / span 2; }
.hc-ww__photos--4 .hc-ww__frame--4 { grid-column: 2; grid-row: 3; }

.hc-ww__photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   Profile
   ========================================================================== */

.hc-profile__fields { margin-top: var(--hc-space-lg); }

.hc-profile__hint { margin-top: var(--hc-space-sm); }

.hc-account__copy {
  margin-top: var(--hc-space-base);
  margin-bottom: var(--hc-space-lg);
  color: var(--hc-mid);
}

.hc-form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hc-space-base);
}

.hc-form-row--address { grid-template-columns: 1.6fr 0.8fr 1fr; }

.hc-form-row .hc-field,
.hc-profile__fields .hc-field { margin: 0; }

.hc-profile__fields > * + * { margin-top: var(--hc-space-base); }

/* Selects lose their native chrome in the reset, so they get their own
   chevron, drawn to match the line icons used everywhere else. */
.hc-select {
  appearance: none;
  -webkit-appearance: none;
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 14px;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237A7570' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

:root[data-theme="dark"] .hc-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239A938A' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.hc-profile__leader-copy {
  margin-top: var(--hc-space-base);
  margin-bottom: var(--hc-space-base);
  color: var(--hc-mid);
}

.hc-switch-row__sub { display: block; margin-top: 2px; }

.hc-about {
  margin-top: var(--hc-space-xxl);
  padding-top: var(--hc-space-lg);
  border-top: var(--hc-hairline) solid var(--hc-rule);
  text-align: center;
}

.hc-about .hc-mark { margin: 0 auto var(--hc-space-base); }
.hc-about .hc-caption + .hc-caption { margin-top: 4px; }
.hc-about__version { margin-top: var(--hc-space-md) !important; }
.hc-about__warn { margin-top: var(--hc-space-md) !important; color: var(--hc-warning); }

/* ==========================================================================
   Leader tools
   ========================================================================== */

.hc-leader__intro {
  margin: var(--hc-space-base) 0 var(--hc-space-lg);
  color: var(--hc-mid);
}

.hc-leader__actions { margin-top: var(--hc-space-lg); }
.hc-leader__actions .hc-btn + .hc-btn { margin-top: var(--hc-space-md); }

.hc-leader__count { margin-bottom: var(--hc-space-sm); }

.hc-member {
  padding-bottom: var(--hc-space-base);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

.hc-member__check { border-top: 0; }

.hc-member__note { margin-top: var(--hc-space-sm); }

.hc-member__input {
  font-size: 15px;
  padding: 10px var(--hc-space-md);
  min-height: var(--hc-tap-min);
}

.hc-member__remove {
  margin-top: var(--hc-space-sm);
  font-size: var(--hc-caption);
}

.hc-addform {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-base);
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
}

.hc-addform__field + .hc-addform__field { margin-top: var(--hc-space-base); }
.hc-addform .hc-btn { margin-top: var(--hc-space-base); }

.hc-prayer-list { margin-top: var(--hc-space-lg); }

.hc-prayer {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-md);
  padding: var(--hc-space-base) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-prayer:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }

.hc-prayer__body { flex: 1 1 auto; min-width: 0; }
.hc-prayer__body .hc-body-serif { margin: 4px 0; }

/* ==========================================================================
   Width guards
   ========================================================================== */

/* --------------------------------------------------------------------------
   The fine print. Privacy policy, terms, and the data screen.

   Long form reading, so it follows the guide reader rather than the settings
   rows: serif body, generous measure, headings that separate with weight and
   space instead of rules. A privacy policy nobody can stand to read is a
   privacy policy that has not really been provided.
   -------------------------------------------------------------------------- */

.hc-legal__date {
  margin-top: var(--hc-space-md);
  color: var(--hc-mid);
}

.hc-legal__block { margin-top: var(--hc-space-xl); }

.hc-legal__heading {
  font-family: var(--hc-sans);
  font-weight: 600;
  font-size: var(--hc-body-sans);
  line-height: var(--hc-body-sans-line);
  letter-spacing: 0.01em;
  color: var(--hc-ink);
  margin-bottom: var(--hc-space-md);
}

/* Some blocks are a continuation of the one above and carry no heading. The
   empty h2 collapses rather than leaving a gap where a title would be. */
.hc-legal__heading:empty { display: none; }

.hc-legal__p + .hc-legal__p { margin-top: var(--hc-space-base); }

.hc-legal__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Hanging bullet, drawn rather than inherited, so it sits on the serif
   baseline and takes the rule color instead of the text color. */
.hc-legal__item {
  position: relative;
  padding-left: var(--hc-space-lg);
}

.hc-legal__item + .hc-legal__item { margin-top: var(--hc-space-md); }

.hc-legal__item::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.7em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--hc-accent);
}

.hc-legal .hc-btn { margin-top: var(--hc-space-base); }

/* The erase action. Kept away from the text above it so a scroll does not
   land a thumb on it, and the confirm state stacks its two choices with the
   safe one underneath. */
.hc-data__action { margin-top: var(--hc-space-lg); }

.hc-data__action--confirm {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-md);
}

.hc-data__action--confirm .hc-btn { margin-top: 0; }

/* 320 wide. Tighten the gutters, never the vertical rhythm. */
@media (max-width: 359px) {
  :root {
    --hc-screen-pad: 16px;
    --hc-card-pad: 16px;
  }

  .hc-sermon__thumb { flex-basis: 64px; width: 64px; }
  .hc-tab__label { font-size: 10px; }
  /* The navigation's two lists come down a step with everything else, and the
     tracking comes off with the size: letter-spacing that reads as considered
     at 20px reads as a word coming apart at 18. */
  .hc-navmenu__group--more .hc-navmenu__link { font-size: 12px; letter-spacing: 0.14em; }
  .hc-navmenu__group--tabs .hc-navmenu__link { font-size: 18px; letter-spacing: 0.08em; }
  .hc-gathering__times { gap: var(--hc-space-sm) var(--hc-space-md); }
  .hc-gathering__time + .hc-gathering__time { padding-left: var(--hc-space-md); }
}

/* Tablet. The column stays a column, it just gets air around it. */
@media (min-width: 768px) {
  .hc-screen { padding-left: var(--hc-space-xl); padding-right: var(--hc-space-xl); }
  .hc-present { max-width: 720px; margin: 0 auto; }
  .hc-present__question { font-size: calc(36px * var(--hc-text-scale)); }
}

/* --- The latest Instagram post, between the greeting and the gathering card.
   4:3 rather than the square Instagram itself uses. A full width 1:1 is around
   350pt tall on a phone, which pushes the gathering card and its service times
   clean off the first screen, and this file's own rule for Home is three
   things above the fold. 4:3 keeps the photograph a hero and keeps Sunday
   visible under it. The stored images are square, so this crops 12.5% off the
   top and bottom, which their compositions survive; 16:9 would not, it cuts
   faces on at least two of them.
   -------------------------------------------------------------------------- */

.hc-latest {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  text-align: left;
  color: var(--hc-ink);
  margin-bottom: var(--hc-space-lg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* A slide that is not a link: a video plays where it sits, and a photo with
   no URL behind it has nowhere to go. Neither one should offer a finger the
   feedback of something that can be pressed. */
.hc-latest--static { cursor: default; }
.hc-latest--static:active { opacity: 1; }

.hc-latest__label {
  display: block;
  margin-bottom: var(--hc-space-sm);
}

.hc-latest__frame {
  /* Relative so the TikTok frame's play badge, which is inset: 0, centres on
     the picture rather than on the screen. */
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  /* Showing while the photograph loads, and the whole frame if it never
     arrives. Same cream as every other piece of missing art in the app. */
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
}

/* The frame is 4:3 by default, which is the crop the photographs above were
   written for. A video picks its own shape instead, because it is shown whole
   rather than cropped: 9x16 for a phone held upright, which is how a two
   minute word from the pastor gets filmed, and the rest for the times it is
   not. The tall ones are capped so a single slide cannot take the whole
   screen and push Sunday off the bottom of it; at that cap the video letter
   boxes against the cream rather than losing anybody's head to a crop. */
.hc-latest__frame--1x1  { aspect-ratio: 1 / 1; }
.hc-latest__frame--16x9 { aspect-ratio: 16 / 9; }
.hc-latest__frame--4x5  { aspect-ratio: 4 / 5; max-height: 62vh; }
.hc-latest__frame--9x16 { aspect-ratio: 9 / 16; max-height: 62vh; }

.hc-latest__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  animation: hc-fade-in var(--hc-dur-base) var(--hc-ease-enter) both;
}

/* Set by the image error listener in app.js, same as the rail's tiles. */
.hc-latest[data-failed="true"] .hc-latest__img { display: none; }

.hc-latest:active { opacity: 0.9; }

.hc-latest__meta {
  display: block;
  margin-top: var(--hc-space-md);
}

/* Three lines, then it stops. An Instagram caption runs to paragraphs and
   trails off into hashtags, and none of that belongs on the front door. The
   whole caption is one tap away on Instagram, which is where it reads
   properly anyway. */
.hc-latest__caption {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--hc-ink);
}

@media (prefers-reduced-motion: reduce) {
  .hc-latest__img { animation: none; }
}

/* --- The carousel these slides live in ------------------------------------
   One slide wide, snapping, with the dots underneath. Same machinery as the
   rail on Connect and for the same reason: an overflowing scroller is a
   gesture every phone already knows, and swipe.js hands the drag to any
   scroller under the finger that still has somewhere to go, so a swipe inside
   this block moves the block and a swipe past its last slide changes tabs.

   Not full bleed, unlike the rail. The rail's overrun is what says there is
   more to the right; here every slide fills the column, and a slide that ran
   off both edges would say the photograph had been cropped rather than that
   there is another one behind it. The dots say it instead.

   With one slide there is no overflow, so there is nothing to scroll, no dots
   are drawn, and this is the single photograph it has always been.
   -------------------------------------------------------------------------- */

.hc-carousel { margin-bottom: var(--hc-space-lg); }

.hc-carousel__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  /* Momentum scrolling inside the Capacitor web view. */
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.hc-carousel__viewport::-webkit-scrollbar { display: none; }

.hc-carousel__track {
  display: flex;
  gap: var(--hc-card-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Every slide is as tall as the tallest one, because they all sit in one
   scroller and a scroller has one height. A phone video is 9:16 and an
   Instagram photograph is 4:3, so that difference is real and has to go
   somewhere: centered, it becomes even air above and below the shorter slide
   and reads as framing. Left at the top, it is a hole under the caption. */
.hc-carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The slide inside carries no margins of its own: the carousel owns the space
   under the whole block, and a margin on the slide would put a gap inside the
   scroller that the snapping would then have to account for. */
.hc-carousel .hc-latest { margin-top: 0; margin-bottom: 0; }

/* contain, not cover. A photograph can lose 12.5% off its top and bottom and
   survive it; a face two feet from a phone camera cannot. Whatever the frame
   does not fill stays cream, the same as every other piece of missing art
   here, so a video that is not quite the shape of its frame reads as a video
   rather than as a mistake. */
.hc-latest__video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.hc-carousel__dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin: var(--hc-space-md) 0 0;
  padding: 0;
  list-style: none;
}

.hc-carousel__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--hc-ink);
  opacity: 0.2;
  transition: opacity var(--hc-dur-base) var(--hc-ease);
}

.hc-carousel__dot[data-on="true"] { opacity: 0.7; }

/* Same answer as the rail: somebody who asked for less motion still has to be
   able to reach the second slide, so the snapping goes and the scrolling
   stays. */
@media (prefers-reduced-motion: reduce) {
  .hc-carousel__viewport { scroll-snap-type: none; }
  .hc-carousel__dot { transition: none; }
}

/* ==========================================================================
   Group
   The sixth tab. Drawn from demo-group-room, with every value coming from
   tokens.css rather than the mockup's copies of them.
   ========================================================================== */

.hc-group__join { display: flex; flex-direction: column; gap: var(--hc-space-md); }
.hc-group__intro { margin: 0 0 var(--hc-space-base); }
.hc-group__hint  { margin: var(--hc-space-md) 0 0; }
.hc-group__carry { margin: var(--hc-space-sm) 0 0; }

/* The same line, on a slide where taking it would cost the group something.
   Warning coloured rather than danger coloured, for the reason the report
   queue is: nothing is wrong, and this is a thing to read before tapping. */
.hc-group__carry--warn { color: var(--hc-warning); }
.hc-group__error { margin: var(--hc-space-sm) 0 0; font-size: var(--hc-caption); color: var(--hc-error); }

.hc-group__actions {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-md);
}

/* --- the guide rails -------------------------------------------------------
   Two of them, one on the way into a room and one inside it, and both are the
   carousel from Home with a card in the slide instead of a photograph. So
   there is nothing here about the gesture, the snapping, or the dots: that is
   all .hc-carousel, unchanged.

   THE SLIDES ARE AS TALL AS THE TALLEST. One scroller has one height, and the
   slide a host can act on carries a sentence and a button the one they are
   already running does not. The carousel centres a short slide in that
   height, which is right for a photograph and wrong for a card: it leaves the
   card floating with air above and below it. These sit at the top instead, so
   every card starts on the same line however tall it is, and they keep their
   own height rather than stretching into a box with a hole in it.
   -------------------------------------------------------------------------- */

.hc-guide-picker .hc-carousel { margin-bottom: 0; }
.hc-guide-picker__hint { margin: var(--hc-space-md) 0 0; text-align: center; }

.hc-guide-slide { justify-content: flex-start; }
.hc-guide-slide__card { width: 100%; }

/* The Sunday the room is actually running, marked by darkening the edge rule
   every card here already carries rather than by adding anything. The word
   "Tonight" above it is what says it; this is only so the right slide is
   recognisable from half a swipe away. */
.hc-guide-slide__card--now { border-left-color: var(--hc-accent-deep); }

.hc-group__offline {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}
.hc-group__offline-icon { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 1px; }

/* The code, typed. One field with the digits spread out, not six boxes. */
.hc-code-input {
  font-family: var(--hc-sans-display);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  padding: var(--hc-space-md);
}

/* --- in the room -------------------------------------------------------- */

.hc-room-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-sm);
  padding-bottom: var(--hc-space-md);
  margin-bottom: var(--hc-space-base);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}
.hc-room-bar__code { letter-spacing: 0.14em; }
.hc-room-bar__live {
  display: inline-flex;
  align-items: center;
  gap: var(--hc-space-xs);
  font-size: var(--hc-caption);
  color: var(--hc-mid);
}
.hc-room-bar__live::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-success);
}
/* Behind, and saying so. The warning hue earns its keep exactly here: nothing
   is wrong, something is pending. */
.hc-room-bar__live--stale { color: var(--hc-warning); }
.hc-room-bar__live--stale::before { background: var(--hc-warning); }

.hc-room-guide { margin-bottom: var(--hc-space-lg); }
.hc-room-guide__title,
.hc-room-questions__title {
  margin: var(--hc-space-xs) 0 var(--hc-space-xs);
  font-family: var(--hc-serif);
  font-size: calc(23px * var(--hc-text-scale));
  line-height: 1.2;
}

/* The questions are named the same way the sermon above them is, so the two
   read as one page. Only the breathing room differs: this one opens a part of
   the room rather than closing a card. */
.hc-room-questions__title { margin: var(--hc-space-lg) 0 0; }

/* What the list is, under its name. Four sentences is a lot for a caption and
   it earns the room: it is the only place the app tells a leader that these
   are a starting point, that editing them is allowed, that what gets typed
   below is not private to the phone it was typed on, and that the night can
   be carried out at the end. */
.hc-room-questions__note { margin: var(--hc-space-sm) 0 0; }

/* --- the host's report queue --------------------------------------------- */
/* Warning coloured, not danger coloured. A report is something to look at,
   and most of them will turn out to be nothing; drawing it in red would make
   a host feel they have to delete to make it go away. It sits above the
   questions because a flag you have to scroll for is a flag nobody reads. */
.hc-queue {
  margin-bottom: var(--hc-space-base);
  padding: var(--hc-card-pad);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-warning);
}
.hc-queue__eyebrow { display: flex; align-items: center; gap: 6px; color: var(--hc-warning); }
.hc-queue__icon { width: 13px; height: 13px; flex: 0 0 auto; }
.hc-queue__title {
  margin: var(--hc-space-xs) 0 var(--hc-space-xs);
  font-family: var(--hc-serif);
  font-size: calc(21px * var(--hc-text-scale));
  line-height: 1.2;
}
.hc-queue__item {
  margin-top: var(--hc-space-md);
  padding-top: var(--hc-space-md);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}
.hc-queue__who {
  margin: 0;
  font-size: var(--hc-caption);
  font-weight: 600;
  line-height: 18px;
}
.hc-queue__reason {
  margin: var(--hc-space-xs) 0 0;
  font-family: var(--hc-serif);
  font-style: italic;
  font-size: var(--hc-caption);
  line-height: 19px;
  color: var(--hc-mid);
}
.hc-queue__text {
  margin: var(--hc-space-sm) 0 0;
  padding-left: var(--hc-space-md);
  border-left: 2px solid var(--hc-rule);
  font-size: var(--hc-body-sans);
  line-height: 1.5;
}
.hc-queue__text--gone { font-style: italic; color: var(--hc-mid); font-size: var(--hc-caption); }
.hc-queue__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--hc-space-sm);
  margin: var(--hc-space-md) calc(var(--hc-space-sm) * -1) 0;
}
/* The tertiary here is a real choice, not a leftover. Pull it back onto the
   grid the way .hc-note__tools does, so the pair reads as two buttons. */
.hc-queue__row .hc-btn--secondary { margin-left: var(--hc-space-sm); }

/* --- the way back from a block ------------------------------------------- */
/* Quiet on purpose. Nobody needs this until they need it, and then it has to
   be somewhere findable, because a blocked person's writing does not arrive
   and so the feed cannot be where you undo it. */
.hc-blocked {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}
.hc-blocked__label { margin: 0; }
.hc-blocked__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-xs);
}
.hc-blocked__name { font-size: var(--hc-body-sans); }

.hc-reveal-all {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-sm);
  margin-bottom: var(--hc-space-base);
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}

.hc-room-q { padding: var(--hc-space-base) 0; border-top: var(--hc-hairline) solid var(--hc-rule); }
.hc-room-q:first-of-type { border-top: 0; }
.hc-room-q__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hc-space-sm);
}
.hc-room-q__num {
  font-family: var(--hc-sans-display);
  font-size: var(--hc-eyebrow);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--hc-accent-deep);
}
.hc-room-q__text { margin: var(--hc-space-sm) 0 0; }
.hc-room-q__tag {
  display: inline-block;
  margin-top: var(--hc-space-sm);
  padding: 3px 8px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-paper-sunk);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hc-accent-deep);
}
.hc-room-q__empty { margin: var(--hc-space-md) 0 0; }
.hc-room-q__mine { margin-top: var(--hc-space-md); }
.hc-room-q__post { margin-top: var(--hc-space-sm); }
.hc-room-q__editrow { display: flex; flex-wrap: wrap; gap: var(--hc-space-sm); margin-top: var(--hc-space-sm); }
.hc-room-q--add { border-top: var(--hc-hairline) solid var(--hc-rule); }

/* --- what people wrote --------------------------------------------------- */

.hc-notes { display: flex; flex-direction: column; gap: var(--hc-space-sm); margin-top: var(--hc-space-md); }

.hc-note {
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-cream);
  border-left: var(--hc-edge-rule) solid var(--hc-accent);
}
.hc-note--mine { background: var(--hc-paper-sunk); border-left-color: var(--hc-accent-deep); }
/* In, but not out. */
.hc-note--waiting { border-left-color: var(--hc-warning); }

.hc-note__who {
  margin: 0;
  font-family: var(--hc-sans-display);
  font-size: var(--hc-eyebrow);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--hc-accent-deep);
}
.hc-note__you {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--hc-mid);
}
.hc-note__text {
  margin: var(--hc-space-xs) 0 0;
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-body-serif) * var(--hc-text-scale));
  line-height: 1.5;
}
.hc-note__flag {
  display: flex;
  align-items: center;
  gap: var(--hc-space-xs);
  margin: var(--hc-space-sm) 0 0;
  font-size: 11.5px;
  color: var(--hc-mid);
}
.hc-note__lock { width: 12px; height: 12px; flex: 0 0 auto; }
/* Negative inline margin so the first button's own padding does not indent
   the row away from the text above it. */
.hc-note__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
  margin: var(--hc-space-xs) calc(var(--hc-space-sm) * -1) 0;
}

/* Waiting on the leader. Dashed, because the answers exist and are simply
   not out yet, which is a different thing from an empty state. */
.hc-locked {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-sm);
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: 1px dashed var(--hc-rule);
  font-size: var(--hc-caption);
  line-height: 18px;
  color: var(--hc-mid);
}
.hc-locked svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 1px; }

/* --- the reveal desk, host only ------------------------------------------ */

.hc-desk {
  margin-top: var(--hc-space-md);
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}
.hc-desk__label { margin: 0 0 var(--hc-space-sm); font-size: 11.5px; color: var(--hc-mid); }
.hc-desk__names { display: flex; flex-wrap: wrap; gap: var(--hc-space-xs); }

.hc-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  padding: 6px 11px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-paper);
  border: 1px solid var(--hc-rule);
  color: var(--hc-mid);
  font-family: var(--hc-sans);
  font-size: var(--hc-caption);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--hc-dur-fast) var(--hc-ease),
              color var(--hc-dur-fast) var(--hc-ease),
              border-color var(--hc-dur-fast) var(--hc-ease);
}
.hc-chip__icon { width: 13px; height: 13px; flex: 0 0 auto; }
.hc-chip[aria-pressed="true"] {
  background: var(--hc-dark);
  border-color: transparent;
  color: var(--hc-on-dark);
}
.hc-chip--act { border-style: dashed; color: var(--hc-accent-deep); }

/* --- the last box, and the end of the night ------------------------------ */

.hc-prayers {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-card-pad);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-cream);
  border: var(--hc-hairline) solid var(--hc-rule);
  border-left: var(--hc-edge-rule) solid var(--hc-accent-deep);
}
.hc-prayers__title {
  margin: var(--hc-space-xs) 0 var(--hc-space-xs);
  font-family: var(--hc-serif);
  font-size: calc(23px * var(--hc-text-scale));
  line-height: 1.2;
}
.hc-prayers .hc-note { background: var(--hc-paper); border-left-color: var(--hc-accent-deep); }

.hc-room-code { margin-top: var(--hc-space-lg); text-align: center; }
/* Read out at the door rather than found at the end of the night. */
.hc-room-code--top { margin-top: 0; margin-bottom: var(--hc-space-lg); }
.hc-room-code__digits {
  margin: var(--hc-space-sm) 0 0;
  font-family: var(--hc-sans-display);
  font-size: 40px;
  font-weight: 800;
  letter-spacing: 0.10em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.hc-wrap {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-card-pad);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}
.hc-wrap__title {
  margin: var(--hc-space-xs) 0 var(--hc-space-xs);
  font-family: var(--hc-serif);
  font-size: calc(23px * var(--hc-text-scale));
  line-height: 1.2;
}
/* Stacked rather than side by side. At 375 across, two buttons in a row put
   "Print everything to PDF" on three lines, and a three line button reads as
   a mistake. Full width also gives the pair a primary and a second. */
.hc-wrap__row { display: flex; flex-direction: column; gap: var(--hc-space-sm); margin-top: var(--hc-space-md); }

/* No markers, so no indent either. base.css strips list-style app wide and a
   left padding with nothing in it just pushes the text off the grid. */
.hc-terms-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-md);
}
.hc-terms-list li { font-size: var(--hc-body-sans); line-height: 1.55; color: var(--hc-mid); }

/* ==========================================================================
   More
   What is behind the ••• tile. A short list of modules, drawn heavier than an
   hc-row because this screen is nothing but the list: at row weight it read
   as a settings page rather than as somewhere to go.
   ========================================================================== */

.hc-module-list {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-base);
}

.hc-module {
  display: flex;
  align-items: center;
  gap: var(--hc-space-base);
  width: 100%;
  text-align: left;
  min-height: var(--hc-tap-min);
  padding: var(--hc-space-base);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
  color: var(--hc-ink);
}

/* The disc keeps the glyph off the text's baseline grid and gives the row a
   fixed left edge, so titles of different lengths still line up. */
.hc-module__disc {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-paper);
  border: var(--hc-hairline) solid var(--hc-rule);
}

.hc-module__icon { width: 20px; height: 20px; color: var(--hc-accent-deep); }

.hc-module__body { flex: 1 1 auto; min-width: 0; display: block; }

.hc-module__title {
  display: block;
  font-family: var(--hc-serif);
  font-weight: 400;
  font-size: calc(19px * var(--hc-text-scale));
  line-height: 1.3;
  margin-bottom: 2px;
}

.hc-more__note { margin-top: var(--hc-space-xl); }

/* Giving, at the bottom of Home. See givingRow() in js/screens/home.js. */
/* Same as the announcement: the "Give" header carries the space now, so this
   keeps no margin of its own. The scripture under the row keeps the blank
   line it is written with, which is a real newline inside one escaped string
   rather than a second paragraph. */
.hc-home__give .hc-caption { white-space: pre-line; }

/* ==========================================================================
   Journal
   The list of everything somebody has written, and the screen for one entry.
   Cards rather than rows, because an entry has a shape: an eyebrow saying
   where it came from, sometimes a quotation, then their own words.
   ========================================================================== */

.hc-journal__intro { margin-top: var(--hc-space-md); color: var(--hc-mid); }

.hc-journal__new { margin-top: var(--hc-space-lg); }

.hc-journal__search { margin-top: var(--hc-space-lg); }

.hc-journal__filters { margin-top: var(--hc-space-md); }

.hc-jlist {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-base);
}

/* The folds. A guide's heading is drawn the way a section header is, eyebrow,
   title and the short accent rule, only it is a button with a count and a
   chevron leading it. A month inside it is the same fold one size down: no
   eyebrow, no rule, a hairline above it the way archive rows sit. */
.hc-jfold--group { margin-top: var(--hc-space-xl); }

.hc-jfold__h { margin: 0; }

.hc-jfold__toggle {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-md);
  width: 100%;
  min-height: var(--hc-tap-min);
  padding: 0 0 0 calc(20px + var(--hc-space-md));
  text-align: left;
  color: var(--hc-ink);
}

.hc-jfold__heading {
  flex: 1 1 auto;
  min-width: 0;
  display: block;
}

.hc-jfold__heading .hc-eyebrow { display: block; }

.hc-jfold__title {
  display: block;
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: calc(25px * var(--hc-text-scale));
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.hc-jfold--group .hc-eyebrow + .hc-jfold__title { margin-top: 8px; }

.hc-jfold__rule {
  display: block;
  margin-top: 12px;
  width: 22%;
  min-width: 56px;
  height: 0.75px;
  background: var(--hc-accent);
}

.hc-jfold__count {
  flex: 0 0 auto;
  align-self: center;
  padding: 0 var(--hc-space-sm);
  border-radius: var(--hc-radius-pill);
  background: var(--hc-cream);
  color: var(--hc-mid);
}

.hc-jfold__chevron {
  position: absolute;
  left: 0;
  top: 10px;
  width: 20px;
  height: 20px;
  stroke: var(--hc-accent-deep);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--hc-dur-base) var(--hc-ease);
}

.hc-jfold__toggle[aria-expanded="true"] .hc-jfold__chevron { transform: rotate(180deg); }

.hc-jfold--month {
  margin-top: var(--hc-space-base);
  padding-top: var(--hc-space-sm);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-jfold--month .hc-jfold__toggle { align-items: center; }

.hc-jfold--month .hc-jfold__title {
  font-size: calc(18px * var(--hc-text-scale));
  font-weight: 700;
}

.hc-jfold--month .hc-jfold__chevron { top: 50%; margin-top: -10px; }

.hc-jfold--month .hc-jfold__toggle[aria-expanded="true"] .hc-jfold__chevron {
  transform: rotate(180deg);
}

.hc-jfold__panel {
  overflow: hidden;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--hc-dur-base) var(--hc-ease);
}

.hc-jfold__panel[data-open="true"] { grid-template-rows: 1fr; }

.hc-jfold__panel > div {
  min-height: 0;
  /* A closed fold's cards are still in the tree, so hide them from the tab
     order and a screen reader too, once the fold has finished closing. */
  visibility: hidden;
  transition: visibility 0s linear var(--hc-dur-base);
}

.hc-jfold__panel[data-open="true"] > div {
  visibility: visible;
  transition-delay: 0s;
}

.hc-jcard {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--hc-space-base);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
  color: var(--hc-ink);
}

.hc-jcard__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-sm);
}

.hc-jcard__pin-icon { width: 14px; height: 14px; color: var(--hc-accent-deep); }

/* The quotation carries the signature left edge the guides use for anchors,
   so a highlight reads as something lifted out of a guide rather than as
   something the person wrote. */
.hc-jcard__quote {
  display: block;
  margin-top: var(--hc-space-sm);
  padding-left: var(--hc-space-md);
  border-left: var(--hc-edge-rule) solid var(--hc-accent);
  font-family: var(--hc-serif);
  font-size: calc(16px * var(--hc-text-scale));
  line-height: 1.45;
  color: var(--hc-ink);
}

.hc-jcard__body {
  display: block;
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-sans);
  font-size: calc(var(--hc-body-sans) * var(--hc-text-scale));
  line-height: 1.5;
  color: var(--hc-mid);
}

.hc-jcard__body--empty { font-style: italic; }

.hc-jcard__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-md);
}

.hc-jcard__refs { color: var(--hc-accent-deep); text-align: right; }

/* Where it is saved, said under every box that saves. Icon and text on one
   line, the way the offline note on the Guide index is drawn. */
.hc-journal__where {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-xl);
  color: var(--hc-mid);
}

.hc-journal__where-icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  color: var(--hc-accent-deep);
}

/* ------------------------------------------------------------- one entry */

.hc-entry__quote {
  margin: 0 0 var(--hc-space-lg);
  padding-left: var(--hc-space-base);
  border-left: var(--hc-edge-rule) solid var(--hc-accent);
}

.hc-entry__quote .hc-caption { margin-top: var(--hc-space-sm); }



.hc-entry__guide { margin-top: var(--hc-space-lg); }

.hc-entry__tag { margin-top: var(--hc-space-md); color: var(--hc-accent-deep); }

.hc-entry__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-lg);
}

/* What you already wrote about tonight's guide, above the answer box in a
   room. See fromJournal() in js/screens/group.js. */

.hc-fromj { margin-top: var(--hc-space-base); }

.hc-fromj__toggle {
  display: flex;
  align-items: center;
  gap: var(--hc-space-sm);
  width: 100%;
  min-height: var(--hc-tap-min);
  padding: 0 var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  border: var(--hc-hairline) dashed var(--hc-rule);
  background: transparent;
  color: var(--hc-accent-deep);
  font-family: var(--hc-sans);
  font-weight: 500;
  font-size: var(--hc-caption);
  text-align: left;
}

.hc-fromj__icon { width: 15px; height: 15px; flex: 0 0 auto; }

.hc-fromj__count {
  margin-left: auto;
  padding: 0 var(--hc-space-sm);
  border-radius: var(--hc-radius-pill);
  background: var(--hc-cream);
  color: var(--hc-mid);
}

.hc-fromj__chevron {
  /* Leads the bar, the same way every other fold in the app does now. Drawn
     last in the markup and moved with `order`, so the toggle keeps its one
     aria-expanded and the [aria-expanded="true"] rule below still finds it. */
  order: -1;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  transition: transform var(--hc-dur-fast) var(--hc-ease);
}

.hc-fromj__toggle[aria-expanded="true"] .hc-fromj__chevron { transform: rotate(180deg); }

.hc-fromj__list {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-sm);
}

.hc-fromj__item {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--hc-space-md);
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
  color: var(--hc-ink);
}

.hc-fromj__quote {
  display: block;
  margin-bottom: var(--hc-space-xs);
  font-family: var(--hc-serif);
  font-size: calc(15px * var(--hc-text-scale));
  color: var(--hc-accent-deep);
}

.hc-fromj__body {
  display: block;
  font-family: var(--hc-sans);
  font-size: calc(var(--hc-body-sans) * var(--hc-text-scale));
  line-height: 1.5;
}

.hc-fromj__note { margin-top: var(--hc-space-xs); }

/* Keeping your own half of a group night. See keepRow() in
   js/screens/group.js and keepTonight() in js/app.js. */
.hc-keep {
  margin-top: var(--hc-space-lg);
  padding-top: var(--hc-space-base);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-keep .hc-caption { margin-top: var(--hc-space-sm); }

/* Your own copy of your own journal, under the note about where it lives. */
.hc-journal__export { margin-top: var(--hc-space-lg); }

.hc-journal__export .hc-caption { margin-top: var(--hc-space-sm); }

/* The Journal lock. The row only exists on a phone that can do it, see
   paintLockRow() in js/app.js. */
.hc-lockrow { margin-top: var(--hc-space-lg); }

.hc-lockrow__note { margin-top: var(--hc-space-sm); }

/* What the Journal is instead of itself while it is locked. Nothing of the
   list is built behind this, so there is nothing to reach by scrolling. */
.hc-lockwall {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--hc-space-xxl) var(--hc-space-base);
}

.hc-lockwall__icon {
  width: 30px;
  height: 30px;
  color: var(--hc-accent-deep);
}

.hc-lockwall__text {
  margin-top: var(--hc-space-base);
  font-family: var(--hc-serif);
  font-size: calc(19px * var(--hc-text-scale));
  color: var(--hc-mid);
}

.hc-lockwall__action { margin-top: var(--hc-space-lg); }

/* --------------------------------------------------------------------------
   Practices. The grid of nine, and the page every one of the nine is drawn
   with. See js/screens/practices.js.
   -------------------------------------------------------------------------- */

.hc-practices__lede {
  margin-top: var(--hc-space-base);
  color: var(--hc-mid);
}

/* ------------------------------------------------------------------ credit

   Whose work the practices are. Sits under the header on the grid and on all
   nine practice pages. Set on the sunk paper with the signature left edge
   rather than in a card, because it is not one more thing to read on the way
   down, it is the frame around everything below it.

   ALPHA BORROWS IT, and shares the selector rather than copying the rules.
   That screen makes the same admission in the same place about somebody
   else's course, and two blocks that say the same thing in two stylesheets
   are two blocks that stop looking alike the first time one is adjusted.
   Different class name because it is a different credit to different people;
   same rules because it is the same moment on the page. */

.hc-ptw,
.hc-alpha-credit {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--hc-space-md);
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-base);
  border-left: var(--hc-edge-rule) solid var(--hc-accent);
  background: var(--hc-paper-sunk);
  border-radius: 0 var(--hc-radius-lg) var(--hc-radius-lg) 0;
}

.hc-ptw__text,
.hc-alpha-credit__text {
  font-family: var(--hc-sans);
  font-size: calc(var(--hc-caption) * var(--hc-text-scale));
  line-height: 1.55;
  color: var(--hc-mid);
}

/* The one name on this screen that has to be read rather than skimmed. */
.hc-ptw__text strong,
.hc-alpha-credit__text strong {
  font-weight: 600;
  color: var(--hc-ink);
}

/* ----------------------------------------------------------- signing up

   Under the grid, centered. The button keeps its own width rather than
   stretching the full column, so it reads as one thing to tap rather than a
   tenth tile in the grid above it.

   Alpha's signup is the same block at the foot of its own page, sharing the
   selector for the same reason the credit above does: one rule, so the two
   ways into a course the church runs cannot drift apart. */

.hc-practice-signup,
.hc-alpha-signup {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--hc-space-md);
  margin-top: var(--hc-space-xxl);
  padding-top: var(--hc-space-lg);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-practice-signup__lead,
.hc-alpha-signup__lead {
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: var(--hc-question-line);
  max-width: 28ch;
}

.hc-practice-signup .hc-btn,
.hc-alpha-signup .hc-btn { width: auto; }

.hc-practice-signup__note,
.hc-alpha-signup__note { color: var(--hc-mid); }

/* Three by three, fixed. Not auto-fit: nine things in a three by three grid
   is the shape people are being shown, and letting a wide phone reflow it to
   four across and then two would make the same screen a different screen
   depending on the handset. The tiles get wider, the arrangement does not. */
.hc-practice-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--hc-space-lg) var(--hc-space-sm);
  margin-top: var(--hc-space-lg);
}

.hc-practice-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hc-space-sm);
  padding: var(--hc-space-xs) 0;
  color: var(--hc-ink);
  text-align: center;
  transition: transform var(--hc-dur-fast) var(--hc-ease);
}

.hc-practice-tile:active { transform: scale(0.96); }

/* The same disc the More rows use, larger. Paper on sunk paper rather than a
   filled circle, so nine of them in a grid read as nine quiet marks instead
   of nine buttons shouting at once. */
.hc-practice-tile__disc {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 76px;
  aspect-ratio: 1 / 1;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-paper-sunk);
  border: var(--hc-hairline) solid var(--hc-rule);
}

.hc-practice-tile__icon {
  width: 30px;
  height: 30px;
  color: var(--hc-accent-deep);
}

.hc-practice-tile__label {
  font-family: var(--hc-sans);
  font-weight: 500;
  font-size: calc(13px * var(--hc-text-scale));
  line-height: 1.25;
}

/* Long labels get one more line rather than a smaller tile. Generosity is the
   widest of the nine and it is what this was measured against. */
@media (max-width: 340px) {
  .hc-practice-tile__label { font-size: calc(12px * var(--hc-text-scale)); }
}

/* ----------------------------------------------------------- one practice */

.hc-practice__p {
  margin-top: var(--hc-space-base);
}

/* Whose words and whose videos, last on the page. Alpha closes the same way
   with the same rule, for the same reason. */
.hc-practice__source,
.hc-alpha__source {
  margin-top: var(--hc-space-xl);
  padding-top: var(--hc-space-base);
  border-top: var(--hc-hairline) solid var(--hc-rule);
  color: var(--hc-mid);
}

.hc-practice-session {
  margin-top: var(--hc-section-top);
}

.hc-practice-session__title {
  display: block;
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-serif);
  font-weight: 400;
  font-size: calc(var(--hc-display-m) * var(--hc-text-scale));
  line-height: var(--hc-display-m-line);
}

/* Same rule under a session heading as under every other heading in the app.
   A session is a section, and it should not look like a new kind of thing. */
.hc-practice-session__rule {
  margin-top: 12px;
  width: 22%;
  min-width: 56px;
  height: 0.75px;
  background: var(--hc-accent);
}

.hc-practice-session__head + * { margin-top: var(--hc-space-base); }

.hc-practice-session__p { margin-top: var(--hc-space-base); }

/* The thing the session actually asks you to go and do. It is set apart with
   the signature left edge rather than in a card, because it is the one line
   on the page a person is meant to carry out of the app with them, and a card
   would file it alongside the teaching instead of after it. */
/* Alpha's day away is set the same way and shares the selector: it is the one
   thing on that page which is not an evening in the numbered run above it, and
   the left edge is how this app has always said "this one is apart". */
.hc-practice-step,
.hc-alpha-away {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-space-md) 0 var(--hc-space-md) var(--hc-space-base);
  border-left: var(--hc-edge-rule) solid var(--hc-accent);
}

.hc-practice-step__label,
.hc-alpha-away__label {
  display: block;
  color: var(--hc-accent-deep);
}

.hc-practice-step__text,
.hc-alpha-away__text {
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: var(--hc-question-line);
}

/* ------------------------------------------------------------------ video

   A poster until it is tapped, then a real player in the same box. The two
   share the aspect ratio so nothing on the page moves when the swap happens,
   which matters more than it sounds on a page with six of them: a video that
   grows on tap pushes everything below it down and takes the thing somebody
   was reading with it. */

.hc-video { margin-top: var(--hc-space-base); }

.hc-video__poster,
.hc-video__frame {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
  background: var(--hc-cream);
}

.hc-video__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hc-video__iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.hc-video__meta {
  margin-top: var(--hc-space-sm);
  color: var(--hc-mid);
}

/* ------------------------------------------------------- the rest of the
   playlist. Trailers, Q&A, whatever else is in there, under their own
   heading so nothing above them is something the sessions never taught. */

.hc-practice-extras {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-lg);
  margin-top: var(--hc-space-base);
}

.hc-practice-extra__title {
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-serif);
  font-size: calc(19px * var(--hc-text-scale));
  line-height: 1.3;
}

/* A thumbnail that did not arrive. The cream block and the play badge stay,
   which is how missing art behaves everywhere else in this app. */
.hc-video__poster[data-failed="true"] .hc-video__thumb { display: none; }

/* The hero line off the practice's own page, under the title. */
.hc-practice__subtitle {
  margin-top: var(--hc-space-md);
  font-family: var(--hc-serif);
  font-style: italic;
  font-size: calc(var(--hc-quote) * var(--hc-text-scale));
  line-height: var(--hc-quote-line);
  color: var(--hc-accent-deep);
}

/* ---------------------------------------------------------------- resources

   What a practice closes with. Stacked blocks rather than cards, because they
   are read once on the way out rather than scanned, and a row of cards here
   would compete with the sessions above them for the same attention. */

.hc-practice-resources {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-xl);
  margin-top: var(--hc-space-base);
}

.hc-practice-resource {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--hc-space-md);
}

/* Their artwork, on their CDN. Sized rather than full bleed: these are book
   covers and podcast art, and stretching one to the column width makes a
   product shot out of something that is really an illustration. */
.hc-practice-resource__art {
  width: 128px;
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
  background: var(--hc-cream);
}

.hc-practice-resource__img {
  display: block;
  width: 100%;
  height: auto;
}

/* The one thing on these screens that needs a network. Without it the block
   still reads, so the empty frame goes rather than sitting there. */
.hc-practice-resource__art[data-failed="true"] { display: none; }

.hc-practice-resource__title {
  font-family: var(--hc-serif);
  font-weight: 400;
  font-size: calc(22px * var(--hc-text-scale));
  line-height: 1.25;
}

.hc-practice-resource__p { margin: 0; }
/* --------------------------------------------------------------------------
   Alpha. One page behind •••, and almost all of it is borrowed: the credit
   block, the signup foot, the left edge, the video poster and the numbered
   question row are all shared selectors defined above and in components.css.
   What is left here is the four things this screen has that no other screen
   does. See js/screens/alpha.js.
   -------------------------------------------------------------------------- */

.hc-alpha__lede {
  margin-top: var(--hc-space-lg);
  color: var(--hc-mid);
}

.hc-alpha__p { margin-top: var(--hc-space-base); }

.hc-alpha__off-season { color: var(--hc-ink); }

/* --- The three parts of a night ------------------------------------------

   Not a card each and not a numbered list. Three of anything on a phone wants
   to be either a row of tiles, which these are far too wordy for, or a stack,
   and a stack is what this is: hairline between, title in sans, sentence in
   the reading serif under it. The hairline is the same one the numbered
   question rows below use, so the two blocks read as one page rather than as
   two designers. */

.hc-alpha-night { margin-top: var(--hc-space-lg); }

.hc-alpha-part {
  padding-top: var(--hc-space-base);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-alpha-part + .hc-alpha-part { margin-top: var(--hc-space-base); }

.hc-alpha-part__title {
  font-family: var(--hc-sans);
  font-weight: 600;
  font-size: calc(var(--hc-caption) * var(--hc-text-scale));
  line-height: 1.3;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hc-accent-deep);
}

.hc-alpha-part__body {
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: var(--hc-question-line);
}

/* --- The eleven questions ------------------------------------------------

   hc-numbered, straight out of components.css, which is the component carried
   from the printed guides and the one the design system says should survive
   intact. Eleven weeks of Alpha is a numbered list of questions, so it is
   drawn with the app's numbered list of questions rather than with something
   invented for this screen. Nothing to style here but the space above it. */

.hc-alpha-questions { margin-top: var(--hc-space-lg); }

/* --- What people ask -----------------------------------------------------

   Question and answer, stacked, no chevron and nothing to tap. These are four
   short answers and hiding them behind a disclosure would cost four taps to
   read what fits on one screen, which is the opposite of what somebody
   deciding whether to come needs. */

.hc-alpha-asked { margin-top: var(--hc-space-lg); }

.hc-alpha-ask {
  padding-top: var(--hc-space-base);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-alpha-ask + .hc-alpha-ask { margin-top: var(--hc-space-base); }

.hc-alpha-ask__q {
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: var(--hc-question-line);
  color: var(--hc-ink);
}

.hc-alpha-ask__a {
  margin-top: var(--hc-space-xs);
  font-family: var(--hc-sans);
  font-size: calc(var(--hc-caption) * var(--hc-text-scale));
  line-height: 1.55;
  color: var(--hc-mid);
}

/* --------------------------------------------------------------------------
   Admin

   Settings -> Admin, drawn only for somebody whose profiles.role is 'admin'.
   Nothing here is a new visual language: the item card is the banner's cream
   surface without the accent edge, the fields are the profile form's fields,
   and the switches are the same switches. An admin screen that looked like an
   admin screen would be the one part of this app that felt like software.
   -------------------------------------------------------------------------- */

.hc-admin__intro {
  margin-top: var(--hc-space-md);
  margin-bottom: var(--hc-space-lg);
  color: var(--hc-mid);
}

.hc-admin__new { margin: var(--hc-space-lg) 0; }

/* Fetch Announcements, directly above Write an announcement and matching it:
   centred, full width, same height. The two are the only ways an announcement
   reaches this screen, so they are a pair, and the small right aligned button
   this used to be read as a utility bolted onto the section rather than as
   half of that pair. The hierarchy is carried by fill alone now, secondary
   over primary, which is enough to say which one is the ordinary press. */
.hc-admin__fetch {
  display: flex;
  justify-content: center;
  margin-top: var(--hc-space-lg);
}

.hc-admin__fetch .hc-btn { margin-top: 0; }

.hc-admin__form > * + * { margin-top: var(--hc-space-lg); }

/* One announcement, page, person or setting in a list. */
.hc-admin__item {
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
  padding: var(--hc-space-base);
  margin-top: var(--hc-space-md);
}

.hc-admin__item-head > * + * { margin-top: 4px; }

/* Buttons wrap rather than shrink. Three small buttons and a long name is a
   real row on a narrow phone, and a squeezed tap target is worse than a
   second line. */
.hc-admin__item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-md);
}

.hc-admin__item-actions .hc-btn { margin-top: 0; }

/* Users, split into Admins, Hosts and Members under the search box. The folds
   are the Journal's, and a row a search has left out is hidden outright. */
.hc-admin__users [hidden] { display: none; }

/* The list is the positioned box so a row's offsetTop is measured from it,
   which is what sizeUserLists() in js/screens/admin.js cuts it off at. Past
   ten people it scrolls inside itself, and the scroll stops at its own ends
   rather than carrying on into the page behind it. flow-root so the first
   row's margin stays inside the list whether or not it is scrolling, or the
   cut would land a margin's width short of the tenth row. */
.hc-admin__users-list {
  position: relative;
  display: flow-root;
}

.hc-admin__users-list[data-scroll="true"] {
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

/* The pinned banner's sentence on App settings while it is not being edited.
   Read as the words themselves, not as a disabled box. */
.hc-admin__banner-text {
  margin: 4px 0 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.hc-admin__loading,
.hc-admin__self {
  color: var(--hc-mid);
  margin-top: var(--hc-space-sm);
}

/* An announcement the newsletter reader parsed and nobody has looked at yet.
   The accent edge is the only thing separating it from the posted rows
   underneath, which is the right amount of difference: it is the same card
   holding the same kind of thing, and the stripe says "this one is waiting on
   you" without inventing a second style of list. Same edge the pinned banner
   uses, for the same reason. See migration 0038. */
.hc-admin__item--review {
  border-left: 3px solid var(--hc-accent);
  border-top-left-radius: var(--hc-radius-sm);
  border-bottom-left-radius: var(--hc-radius-sm);
}

/* The dates the model guessed. Set apart from the body above it because it is
   the line most likely to be wrong and so the line most worth reading twice. */
.hc-admin__review-dates { color: var(--hc-mid); }

.hc-admin__intro-note {
  color: var(--hc-mid);
  margin-top: var(--hc-space-sm);
  margin-bottom: var(--hc-space-md);
}

.hc-admin__warn {
  color: var(--hc-accent-deep);
  margin-top: var(--hc-space-sm);
}

/* ---------------------------------------------------------- merging by hand

   The panel behind "Merge with", drawn by mergePanel() in js/components.js.
   It replaces the list on whichever screen put it up, so it is styled as a
   review card rather than as a dialog: the same stripe, the same padding, and
   nothing that says "modal", because it is not one and backing out of it costs
   a tap either way.

   THE DIFF IS THE WHOLE POINT and it is styled to be read rather than skimmed.
   The old value is struck through above the new one, in the quiet colour, so
   a glance down the left edge answers "what is this replacing" and a glance
   down the right answers "with what". Both are given in full; a preview that
   truncates the body is a preview of the wrong thing. */
.hc-merge__diff {
  margin: var(--hc-space-md) 0 0;
  display: grid;
  gap: var(--hc-space-md);
}

.hc-merge__field {
  color: var(--hc-mid);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.75rem;
}

.hc-merge__values {
  margin: var(--hc-space-xs) 0 0;
  display: grid;
  gap: var(--hc-space-xs);
  border-left: 2px solid var(--hc-rule);
  padding-left: var(--hc-space-sm);
}

.hc-merge__before {
  color: var(--hc-mid);
  text-decoration: line-through;
}

/* A field that was empty. Struck-through nothing reads as a mistake, so the
   word is said and the strike comes off. */
.hc-merge__before--none { text-decoration: none; font-style: italic; }

.hc-merge__after { margin: 0; }

/* Who approved a thing out of the newsletter queue, from migration 0043. An
   internal note on an admin-only screen: quieter than the body above it,
   because it is a record rather than something to act on, and not warning
   coloured, because nothing is wrong. */
.hc-admin__approved {
  color: var(--hc-mid);
  margin-top: var(--hc-space-sm);
}

/* The picture block on the announcement form, and the link block under it.
   Both are lists of things with previews, so they share the preview. */
.hc-admin__image > * + *,
.hc-admin__link > * + * { margin-top: var(--hc-space-md); }

/* One picture in the list: its preview, and the box holding its address. */
.hc-admin__image-row + .hc-admin__image-row { margin-top: var(--hc-space-lg); }
.hc-admin__image-row > * + * { margin-top: var(--hc-space-sm); }

/* A preview with its own remove in its own top right corner. Every thumbnail
   on this form carries one, the pictures and the link's alike, so "take this
   one off" is the same gesture wherever somebody meets it. */
.hc-admin__thumb {
  position: relative;
  display: block;
  width: 100%;
  max-width: 260px;
}

.hc-admin__thumb img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--hc-radius-sm);
  background: var(--hc-paper-sunk);
  display: block;
}

/* Set by the image error listener in app.js. A link somebody mistyped shows
   the cream block rather than the web view's broken image glyph. */
.hc-admin__thumb[data-failed="true"] img { display: none; }

/* On the picture rather than beside it, because the picture is what it takes
   away. The disc is the app's paper at full opacity so the x reads over a
   photograph of anything, including a white wall. */
.hc-admin__thumb-x {
  position: absolute;
  top: var(--hc-space-sm);
  right: var(--hc-space-sm);
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--hc-paper);
  color: var(--hc-ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}

.hc-admin__thumb-x svg {
  width: 15px; height: 15px;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.hc-admin__thumb-x:active { opacity: 0.6; }

/* The two ways to add a picture, side by side, wrapping on a narrow phone
   rather than shrinking into two half buttons. */
.hc-admin__image-add {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
}

.hc-admin__image-add > * { flex: 1 1 10rem; }
.hc-admin__image-add .hc-btn { margin-top: 0; width: 100%; }

/* A file input cannot be styled, so the real one is hidden and its <label>
   carries the button. Clicking a label opens the picker natively, which is
   why this is a label and not a button with a click handler on it. */
.hc-admin__file { display: block; }
.hc-admin__file .hc-btn { width: 100%; }

/* The writing surface on the announcement form. Shorter than the Journal's,
   which owns a whole screen: this one has a dozen fields under it and a box
   that fills a third of the phone puts the Save button two scrolls away. */
.hc-rt--admin { min-height: 20vh; }

/* The caption under a field, explaining what leaving it empty does. */
.hc-field__help {
  display: block;
  margin-top: 6px;
  color: var(--hc-mid);
}

/* --------------------------------------------------------------------------
   A content page

   One screen for every row in content_pages. Nothing but prose, so the only
   thing to say is how far apart the paragraphs sit.
   -------------------------------------------------------------------------- */

.hc-page__lede + .hc-page__lede,
.hc-page__text + .hc-page__text { margin-top: var(--hc-space-base); }

.hc-page__lede { margin-top: var(--hc-space-md); }
.hc-page__text { margin-top: var(--hc-space-md); }


/* --------------------------------------------------------------------------
   One announcement

   The page behind a card on Home. See js/screens/announcement.js.

   Nothing here is a new visual language either. The words are the serif every
   other piece of prose in this app is set in, the pictures are the same 4:3
   frame the Instagram rail and the card use, and the video is the same poster
   and play badge as a practice's. What is new is the link card, and it is the
   row from Connect with a photograph on the front.
   -------------------------------------------------------------------------- */

.hc-announce__note {
  margin-top: var(--hc-space-md);
  color: var(--hc-accent-deep);
}

/* Who posted it, drawn only for an admin or a leader. Tighter to the header
   than the full paragraph gap `.hc-section-header + *` would give it, because
   it belongs to the date in the label above rather than to the words below: a
   byline set a paragraph away reads as the announcement opening with one.
   Deliberately quiet, in the caption colour the class already carries rather
   than the accent the window note uses, since this is an aside to the church's
   own staff and not something the church is saying. */
.hc-section-header + .hc-announce__by { margin-top: var(--hc-space-sm); }

.hc-announce__text + .hc-announce__text { margin-top: var(--hc-space-base); }
.hc-announce__text { margin-top: var(--hc-space-md); }

/* Add to calendar, and the when and where under it. The button is the same
   hc-inline-link Connect draws, so it needs no rules of its own; this is the
   block around it, set off from the words above so the one thing on the page
   a person acts on does not read as another paragraph. */
.hc-announce__calendar {
  margin-top: var(--hc-space-lg);
  padding-top: var(--hc-space-md);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-announce__calendar .hc-caption {
  margin-top: var(--hc-space-sm);
  color: var(--hc-mid);
}

/* Markup somebody typed, after the sanitizer. Only seven tags can be in here
   and every one of them is given a size, because a paragraph with no rule is
   a paragraph at whatever the browser's default happens to be.

   Set in the serif rather than the sans. This is the church writing to the
   church at length, which is what the serif is for everywhere else in this
   app, and it is the one thing that keeps a formatted announcement from
   reading like a form. */
.hc-rich {
  margin-top: var(--hc-space-base);
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-body-serif) * var(--hc-text-scale));
  line-height: 1.6;
  color: var(--hc-ink);
  /* Long words and pasted URLs must not push the screen sideways. */
  overflow-wrap: break-word;
}

.hc-rich p { margin: 0 0 var(--hc-space-base); }
.hc-rich p:last-child { margin-bottom: 0; }
.hc-rich ul, .hc-rich ol { margin: 0 0 var(--hc-space-base); padding-left: 1.4em; }
.hc-rich ul { list-style: disc; }
.hc-rich ol { list-style: decimal; }
.hc-rich li { margin-bottom: var(--hc-space-xs); }
.hc-rich strong { font-weight: 600; }

/* A link in an announcement, which unlike a scripture reference in a journal
   entry is a destination somebody is meant to notice. Underlined in the
   accent, and it opens in the phone's own browser: every <a> in this app goes
   through openExternal(), see the click listener in js/app.js. */
.hc-rich a {
  color: var(--hc-accent-deep);
  text-decoration: none;
  border-bottom: var(--hc-hairline) solid var(--hc-accent);
}

/* Stacked, not a carousel. Two pictures of a serve day are two things to see
   and not a gesture to discover. */
.hc-announce__gallery {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-md);
  margin-top: var(--hc-space-base);
}

/* --- the link card ------------------------------------------------------- */

.hc-linkcard {
  display: flex;
  align-items: center;
  gap: var(--hc-space-md);
  width: 100%;
  margin-top: var(--hc-space-base);
  padding: var(--hc-space-md);
  text-align: left;
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
  color: inherit;
}

.hc-linkcard:active { opacity: 0.85; }

/* Square and small, because the thumbnail is a hint about where the tap goes
   and not the picture on the announcement. The pictures above are that. */
.hc-linkcard__frame {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: var(--hc-radius-sm);
  overflow: hidden;
  background: var(--hc-paper-sunk);
}

.hc-linkcard__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hc-linkcard__frame[data-failed="true"] .hc-linkcard__img { display: none; }

.hc-linkcard__body { flex: 1 1 auto; min-width: 0; }

.hc-linkcard__title {
  display: block;
  font-family: var(--hc-serif);
  font-size: calc(17px * var(--hc-text-scale));
  line-height: 1.35;
}

/* The host, and it is always drawn even when the title above it is the same
   words: a link card that does not say where it goes is a link card asking
   somebody to trust it. One line, ellipsised, never wrapped. */
.hc-linkcard__host {
  display: block;
  margin-top: 2px;
  color: var(--hc-mid);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hc-linkcard__icon {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  stroke: var(--hc-mid);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

/* --------------------------------------------------------------------------
   The announcement archive

   Where the archive box in the corner of a card on Home puts it, and the way
   back out. See js/screens/announcement-archive.js.

   Nothing here is a new visual language. The rows are the same .hc-banner card
   Home draws, the tick box is the one a guide's coverage boxes use, and both
   links are the .hc-inline-link Connect and the Add to calendar row already
   carry. What this section adds is only the spacing around them, and the one
   rule that makes an archived card read as put away rather than as news.
   -------------------------------------------------------------------------- */

/* The line under the last announcement on Home. In brackets, in the caption
   size, sitting under the list rather than in it: it is a footnote to the
   announcements above and not a sixth thing on the front door. Underlined
   because it is the only place on Home where a run of plain-looking words is
   a destination, and nothing else in that column is. */
.hc-home__archive-line {
  margin-top: var(--hc-space-md);
}

.hc-archive-link {
  min-height: auto;
  padding: var(--hc-space-sm) 0;
  font-weight: 500;
  color: var(--hc-mid);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.hc-archive-link:active { opacity: 0.7; }

/* What archiving is, said once under the heading. The one thing somebody
   opening this screen might reasonably fear is that they have done something
   to the church's announcements rather than to their own copy of them. */
.hc-archive__blurb {
  margin-top: var(--hc-space-sm);
  color: var(--hc-mid);
}

/* Above the top row, and hidden by the `hidden` attribute until something is
   ticked. Not removed from the markup: a tick has to show this line without
   rebuilding the list under the thumb that is ticking. */
.hc-archive__restore-line {
  margin-top: var(--hc-space-lg);
  padding-bottom: var(--hc-space-sm);
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

.hc-archive__restore {
  min-height: var(--hc-tap-min);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.hc-archive__restore:active { opacity: 0.7; }

.hc-archive__list { margin-top: var(--hc-space-base); }

/* An archived card, which is the same card with its voice down. The accent
   rule down its left edge is what makes an announcement on Home read as
   something the church is saying today, and a list of things somebody has
   already put away should not say that twelve times over. The rule stays,
   because it is the shape of the card, and it goes grey. */
.hc-banner--archived {
  border-left-color: var(--hc-rule);
  background: var(--hc-paper-sunk);
}

.hc-banner--archived .hc-banner__cue { color: var(--hc-mid); }

/* The looping band of film at the head of a practice page. Sized like a wide
   strip rather than a 16:9 block, because it is a header and not something
   anybody is meant to sit and watch. Pointer events off: there is nothing to
   tap and a stray tap that did nothing would feel broken. */
.hc-practice-hero {
  position: relative;
  width: 100%;
  aspect-ratio: 21 / 9;
  margin-top: var(--hc-space-base);
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
  background: var(--hc-cream);
  pointer-events: none;
}

.hc-practice-hero__frame {
  position: absolute;
  /* A background Vimeo embed letterboxes itself to its own aspect ratio, so
     the frame is oversized and centred and the strip crops it, rather than
     the strip showing two black bars. */
  top: 50%;
  left: 50%;
  width: 178%;
  height: 178%;
  transform: translate(-50%, -50%);
  border: 0;
}

/* A hero served as a plain file needs none of the iframe's letterbox
   correction: it is the video itself and it covers the strip directly. */
.hc-practice-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   Worship
   What the band played on Sunday. A week header you can swipe, then the songs
   under it as records: art first, then the name, then who sings it.

   THE LIST IS CENTERED AND THE REST OF THE APP IS NOT. Every other screen
   here is a left aligned column, because every other screen is mostly words
   and words are read down an edge. This one is four album covers, and a
   square has no edge to hang a column on: ranged left, the art and the two
   lines under it stop being one object and become a picture with a caption
   beside it. Centered, each song is a record sleeve with its title under it,
   which is the thing being described.
   -------------------------------------------------------------------------- */

.hc-worship__head {
  position: relative;
  margin-top: var(--hc-space-md);
}

/* The header is what you drag, so it is what carries the week. The block is
   centered and given room to breathe on both sides, which is also what keeps
   the chevrons off the words at the widest date this app can print. */
.hc-worship-week {
  text-align: center;
  padding: 0 var(--hc-space-xl);
}

.hc-worship-week__date { display: block; color: var(--hc-accent-deep); }
.hc-worship-week__title { margin-top: 6px; }

/* The date and the name are one tap target: a tap lifts the calendar sheet
   (js/screens/worship.js), a sideways drag still scrolls the rail. Same
   arrangement as the week header on HomeKids. */
.hc-worship-week__open {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-worship-week__open:active .hc-worship-week__title { opacity: 0.7; }
.hc-worship-week__cal {
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-left: 6px;
  vertical-align: -2px;
}
.hc-worship-cal__head { justify-content: center; margin-top: var(--hc-space-sm); }
.hc-worship-cal__label { min-width: 9em; }

/* The two chevrons, laid over the ends of the header rather than beside it,
   so the slide keeps the full width for a long sermon title and the arrows
   sit in the air the padding above already reserved for them. */
.hc-worship__arrow {
  position: absolute;
  top: 0;
  bottom: var(--hc-space-lg);   /* clear of the dots under the rail */
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--hc-tap-min);
  color: var(--hc-accent-deep);
  transition: opacity var(--hc-dur-fast) var(--hc-ease);
}

.hc-worship__arrow--prev { left: calc(var(--hc-space-sm) * -1); }
.hc-worship__arrow--next { right: calc(var(--hc-space-sm) * -1); }

.hc-worship__arrow svg { width: 20px; height: 20px; }

/* At the ends the arrow stays where it is and stops being a target, so the
   header does not change shape on the first and last week. */
.hc-worship__arrow[disabled] {
  opacity: 0.18;
  pointer-events: none;
}

.hc-worship__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.hc-worship__links:empty { display: none; }

.hc-worship__songs { margin-top: var(--hc-space-lg); }

/* ---- the songs ---- */

.hc-song-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-xxl);
}

.hc-song { text-align: center; }

/* The art is the biggest thing on the screen, which is the whole design of
   this page, and it is capped so that it stays a record sleeve on a tablet
   rather than growing into a poster. */
.hc-song__art {
  position: relative;
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
  border-radius: var(--hc-radius-lg);
  overflow: hidden;
}

.hc-song__art .hc-cover { width: 100%; }

.hc-song__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Art that never arrived. The drawn cover underneath is already there, so
   taking the photograph away is the whole fix. Same move as a series slide. */
.hc-song__art[data-failed="true"] .hc-song__img { display: none; }

.hc-song__title { margin-top: var(--hc-space-base); }
.hc-song__artist { margin-top: 2px; }

/* One row of marks, centered under the words, sized and spaced the way the
   church's own social row is, because they are the same object doing the same
   job: a short row of somebody else's logos, each one a way out of the app. */
.hc-song__links {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-md);
}

.hc-song__link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--hc-tap-min);
  height: var(--hc-tap-min);
  color: var(--hc-ink);
}

.hc-song__brand { width: 22px; height: 22px; }

/* Lyrics is words, not a mark, and it is set as the app's own link rather
   than as a button: it is the one thing in this row that is read rather than
   listened to, and a fourth disc would say it was a fourth platform. */
.hc-song__lyrics {
  min-height: var(--hc-tap-min);
  padding: 0 var(--hc-space-sm);
  color: var(--hc-accent-deep);
  font-family: var(--hc-sans);
  font-weight: 600;
  font-size: var(--hc-caption);
}

/* --------------------------------------------------------------------------
   Search. The box under the heading, then the list.

   A pushed view, so it clears the header the way every screen does and
   nothing else on it is chrome: no filters, no tabs, no rail. What somebody
   types is the only control on the page.
   -------------------------------------------------------------------------- */

.hc-search__field { margin-top: var(--hc-space-lg); }

/* The magnifier sits inside the field rather than beside it, so the field is
   still the full width of the screen and still one tap target. Absolute over
   the input with the input padded to clear it, which keeps the 16px font size
   the input needs to stop iOS zooming the page on focus. */
.hc-search__box {
  position: relative;
  display: block;
}

.hc-search__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  color: var(--hc-mid);
  pointer-events: none;
}

.hc-search__input { padding-left: 44px; }

/* Safari draws its own clear button on type="search" and it is the right
   control in the right place, so it is left alone. What is taken away is the
   decoration around it, which does not match anything else in this app. */
.hc-search__input::-webkit-search-decoration,
.hc-search__input::-webkit-search-results-button,
.hc-search__input::-webkit-search-results-decoration {
  -webkit-appearance: none;
}

.hc-search__results { margin-top: var(--hc-space-lg); }

.hc-search__hint {
  color: var(--hc-mid);
  font-size: calc(var(--hc-body-serif) * var(--hc-text-scale));
  line-height: var(--hc-body-serif-line);
}

.hc-search__count {
  color: var(--hc-mid);
  margin-bottom: var(--hc-space-sm);
}

/* --------------------------------------------------------------- one result

   A row, not a card. There can be sixty of them and a column of sixty cards
   is a wall: the hairline between rows is enough separation for a list you
   are scanning rather than reading. */
.hc-results {
  display: flex;
  flex-direction: column;
}

.hc-result {
  display: flex;
  align-items: flex-start;
  gap: var(--hc-space-base);
  width: 100%;
  padding: var(--hc-space-base) 0;
  text-align: left;
  border-bottom: var(--hc-hairline) solid var(--hc-rule);
}

.hc-result:first-child { border-top: var(--hc-hairline) solid var(--hc-rule); }

.hc-result:active { background: var(--hc-paper-sunk); }

.hc-result__body {
  flex: 1 1 auto;
  min-width: 0;
}

/* What kind of thing this is, above the name of it. The list mixes messages,
   guides, events and screens, and without this line a result is a sentence
   with no idea what tapping it will open. */
.hc-result__kind {
  display: block;
  color: var(--hc-accent-deep);
}

.hc-result__title {
  display: block;
  margin-top: 4px;
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: calc(17px * var(--hc-text-scale));
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--hc-ink);
}

.hc-result__sub {
  display: block;
  margin-top: 2px;
}

/* The words, where they were found. Two lines and then it stops: a snippet
   is there to prove the match, not to be read instead of the page. */
.hc-result__snippet {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 6px;
  font-family: var(--hc-serif);
  font-size: calc(14px * var(--hc-text-scale));
  line-height: 1.45;
  color: var(--hc-mid);
}

/* The matched words. The same wash a kept sentence in a guide gets, because
   it is the same gesture: these are the words, in this text, that somebody
   asked about. A <mark> comes out of the browser bright yellow, which would
   be the loudest thing in a two-palette app, so the background is replaced
   rather than tinted. The ink goes back to full strength inside the mark, so
   the match reads out of the grey line around it. */
.hc-search__hit {
  background: color-mix(in srgb, var(--hc-accent) 34%, transparent);
  color: var(--hc-ink);
  border-radius: 2px;
  padding: 0;
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  .hc-search__hit { background: var(--hc-cream); }
}

.hc-result__chevron {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 18px;
  color: var(--hc-mid);
}

/* --------------------------------------------------------------------------
   Cal
   The church's calendar: a month you can walk through, the day you opened
   under it, and the upcoming events under that.

   THE GRID IS SEVEN EQUAL COLUMNS AND NOTHING ELSE. No week numbers, no
   greyed out days from the months either side. On a 375pt phone, inside the
   screen's own 20pt padding, a column is 47.8pt wide, which is what makes a
   44pt tap target fit with room around it: the day is the full width of its
   column and 44 tall, so the highlight reads as a rounded tile rather than
   as a circle squeezed into a gap. That measurement is why the day is not a
   fixed size square. Nothing here goes under --hc-tap-min.

   ONLY A DAY WITH SOMETHING ON IT IS A BUTTON. The rest are spans. A grid
   where every cell answers a tap with "nothing here" is a grid that asked
   for the tap.
   -------------------------------------------------------------------------- */

.hc-cal { margin-top: var(--hc-space-lg); }

/* Months on the left, years on the right. Two steppers rather than one, so a
   date eight months out is two taps rather than eight. */
.hc-cal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hc-space-sm);
}

.hc-cal__stepper {
  display: flex;
  align-items: center;
}

.hc-cal__step {
  width: var(--hc-tap-min);
  height: var(--hc-tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  color: var(--hc-ink);
  border-radius: var(--hc-radius-pill);
  cursor: pointer;
}

.hc-cal__step:active { background: var(--hc-paper-sunk); }

.hc-cal__step-icon {
  width: 20px;
  height: 20px;
}

/* The month name and the year, sized to the widest each can be. Without the
   min-width the chevrons walk sideways between May and September, which
   makes a thumb that is stepping through months miss the second tap. */
.hc-cal__stepper-label {
  font-family: var(--hc-sans-display);
  font-size: calc(17px * var(--hc-text-scale));
  font-weight: 600;
  color: var(--hc-ink);
  text-align: center;
}

.hc-cal__stepper:first-child .hc-cal__stepper-label { min-width: 5.6em; }
.hc-cal__stepper + .hc-cal__stepper .hc-cal__stepper-label { min-width: 3em; }

.hc-cal__grid { margin-top: var(--hc-space-sm); }

.hc-cal__row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.hc-cal__row--head { margin-bottom: var(--hc-space-xs); }

.hc-cal__dow {
  text-align: center;
  font-size: var(--hc-eyebrow);
  line-height: var(--hc-eyebrow-line);
  letter-spacing: var(--hc-track-eyebrow);
  text-transform: uppercase;
  color: var(--hc-mid);
}

.hc-cal__cell {
  display: flex;
  align-items: center;
  justify-content: center;
}

.hc-cal__day {
  position: relative;
  width: 100%;
  height: var(--hc-tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  border-radius: var(--hc-radius-md);
  font-family: var(--hc-sans);
  font-size: calc(15px * var(--hc-text-scale));
  color: var(--hc-mid);
}

/* A day with nothing on it is a span, so this is the button's cursor only. */
button.hc-cal__day { cursor: pointer; }

/* Something is happening. Full strength ink and a dot under the number,
   which is the highlight the screen promises: the days worth looking at are
   the ones that stand out from the month around them. */
.hc-cal__day--has {
  color: var(--hc-ink);
  font-weight: 600;
  background: var(--hc-cream);
}

.hc-cal__dot {
  position: absolute;
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-accent-deep);
}

/* Today, whether or not anything is on it. A ring rather than a fill, so it
   never competes with the day somebody has actually opened. */
.hc-cal__day--today {
  box-shadow: inset 0 0 0 1.5px var(--hc-rule);
  color: var(--hc-ink);
}

.hc-cal__day--open {
  background: var(--hc-dark);
  color: var(--hc-on-dark);
  box-shadow: none;
}

.hc-cal__day--open .hc-cal__dot { background: var(--hc-on-dark); }

.hc-cal__today {
  margin-top: var(--hc-space-sm);
  text-align: center;
}

/* The day somebody opened. A card rather than a list, because it is one day
   lifted out of the grid above it and it has to read as an answer to the tap
   that opened it. */
.hc-cal__panel {
  margin-top: var(--hc-space-base);
  padding: var(--hc-card-pad);
  background: var(--hc-cream);
  border-radius: var(--hc-radius-lg);
}

.hc-cal__panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--hc-space-sm);
}

.hc-cal__panel-close {
  flex: 0 0 auto;
  width: var(--hc-tap-min);
  height: var(--hc-tap-min);
  margin: calc(var(--hc-space-md) * -1) calc(var(--hc-space-md) * -1) 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  color: var(--hc-mid);
  border-radius: var(--hc-radius-pill);
  cursor: pointer;
}

.hc-cal__panel-close-icon {
  width: 18px;
  height: 18px;
}

.hc-cal__panel-event { margin-top: var(--hc-space-md); }

.hc-cal__panel-event + .hc-cal__panel-event {
  margin-top: var(--hc-space-base);
  padding-top: var(--hc-space-base);
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

/* An admin's two controls in the corner of an event: what this is, and
   whether it should be here at all. Absolutely placed so they sit level with
   the date, and the two lines beside them are given the room back, because a
   title running under a delete button is a title you cannot read and a button
   you press by accident. */
.hc-event--managed { position: relative; }

.hc-event--managed .hc-eyebrow,
.hc-event--managed .hc-row__title {
  padding-right: calc(var(--hc-tap-min) * 2);
}

.hc-event__admin {
  position: absolute;
  top: var(--hc-space-sm);
  right: 0;
  display: flex;
}

.hc-event__admin-btn {
  width: var(--hc-tap-min);
  height: var(--hc-tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  color: var(--hc-mid);
  border-radius: var(--hc-radius-pill);
  cursor: pointer;
}

.hc-event__admin-btn:active { background: var(--hc-paper-sunk); }
.hc-event__admin-btn[disabled] { opacity: 0.5; }

/* The x is the one destructive control on this screen, so it is the one
   thing on it drawn in the error colour. */
.hc-event__admin-btn--x { color: var(--hc-error); }

.hc-event__admin-icon {
  width: 18px;
  height: 18px;
}

.hc-cal__add { margin-top: var(--hc-space-md); }

/* Subscribe, under the month and the open day. A small secondary button and
   not a section of its own: it is a thing you do once, and the month above
   and the list below are what the screen is for. */
.hc-cal__subscribe { margin-top: var(--hc-space-base); }

/* The four choices in the subscribe sheet, one to a row, so each is a
   thumb's worth of target and the labels never wrap beside each other. */
.hc-cal__subscribe-choices {
  display: flex;
  flex-direction: column;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-lg);
}

.hc-cal__form { margin-top: var(--hc-space-base); }

.hc-cal__form > .hc-eyebrow { margin-bottom: var(--hc-space-md); }

.hc-cal__form-actions {
  display: flex;
  align-items: center;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-lg);
}

/* The row already carries the gap the form's own rule would add to each
   button, and taking it twice puts Save and Cancel a long way below the last
   field they belong to. */
.hc-cal__form-actions .hc-btn { margin-top: 0; }

/* ------------------------------------------------ the other days it runs

   The list of extra days on the event form, from migration 0074. A block
   rather than a second date box, because "Friday to Sunday" and "two Sundays
   three weeks apart" are the same thing to a calendar and a range would only
   express the first.

   Each day is a chip with an x, which is the same shape the announcement form
   uses for its pictures. One idea, said the same way in both places: here is a
   thing you added, here is how to take it off.

   NAMED __pick AND NOT __day, and the reason is a bug that shipped. These were
   called hc-cal__day, which is ALREADY the class on every cell of the month
   grid four hundred lines above. Same name, later in the file, so these rules
   won: every date in the grid grew a circle, and the day somebody had open
   lost its fill. Nothing in the grid's own CSS had changed — it was simply
   being overruled by a block that had no business naming itself that.

   The grid is `__day`. These are `__pick`, because what they are is the days
   somebody picked. */
.hc-cal__picks { margin-top: var(--hc-space-base); }

.hc-cal__pick-list {
  list-style: none;
  margin: var(--hc-space-sm) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-sm);
}

.hc-cal__pick {
  display: inline-flex;
  align-items: center;
  gap: var(--hc-space-xs);
  padding: var(--hc-space-xs) var(--hc-space-xs) var(--hc-space-xs) var(--hc-space-md);
  border: 1px solid var(--hc-rule);
  border-radius: var(--hc-radius-pill);
  background: var(--hc-paper-sunk);
}

.hc-cal__pick-x {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  color: var(--hc-mid);
  border-radius: var(--hc-radius-pill);
  cursor: pointer;
}

.hc-cal__pick-x:active { background: var(--hc-paper); }
.hc-cal__pick-icon { width: 14px; height: 14px; }

/* The empty box and the button that reads it. They sit on one line on
   anything with room and stack on a narrow phone, where a date input is
   already as wide as the screen wants to be. */
.hc-cal__pick-add {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-sm);
}

.hc-cal__pick-add .hc-input { flex: 1 1 10rem; }
.hc-cal__pick-add .hc-btn { margin-top: 0; }

/* "Also October 11 and October 18", under an event that runs on more than one
   day. Quieter than the time and the place above it, because it is the second
   question somebody asks of a row and not the first. */
.hc-event__more-days { color: var(--hc-mid); }

/* --------------------------------------------------------------------------
   HomeKids
   The one page in the app read by somebody who may be four. Everything here is
   the house style turned up a notch rather than a second style: the same
   paper, cream and taupe, the same eyebrow over a heavy title, with bigger
   targets, bigger reading type, and one colour per age group so a kid who
   cannot read yet can still find their own button. The colours are the
   house's muted three, sage, amber and brick, never anything brighter.

   The one moment of delight is the design system's own: a finished checklist
   gets a soft warm wash and a gold star. No confetti, no bounce.
   -------------------------------------------------------------------------- */

.hc-kids { --hc-kids-tone: var(--hc-accent-deep); }

/* ---- the three groups ---- */

.hc-kids-groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--hc-space-sm);
  margin-top: var(--hc-space-base);
}

.hc-kids-group--sage  { --hc-kids-tone: var(--hc-success); }
.hc-kids-group--amber { --hc-kids-tone: var(--hc-warning); }
.hc-kids-group--brick { --hc-kids-tone: var(--hc-error); }

.hc-kids-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  min-height: 88px;
  padding: var(--hc-space-md) var(--hc-space-xs);
  border-radius: var(--hc-radius-lg);
  border: 1px solid var(--hc-rule);
  background: transparent;
  color: var(--hc-ink);
  text-align: center;
  transition: background var(--hc-dur-fast) var(--hc-ease),
              border-color var(--hc-dur-fast) var(--hc-ease);
}

.hc-kids-group__dot {
  width: 14px;
  height: 14px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-kids-tone);
}

.hc-kids-group__name {
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: calc(14px * var(--hc-text-scale));
  line-height: 1.15;
}

.hc-kids-group__ages {
  font-family: var(--hc-sans);
  font-size: calc(var(--hc-caption) * var(--hc-text-scale));
  color: var(--hc-mid);
}

.hc-kids-group[aria-pressed="true"] {
  background: var(--hc-cream);
  border-color: var(--hc-kids-tone);
  box-shadow: inset 0 0 0 1px var(--hc-kids-tone);
}

/* ---- the week ---- */

.hc-kids-week { margin-top: var(--hc-space-xl); }
/* Each Sunday's slide is one tap target: a tap lifts the calendar sheet
   (js/screens/homekids.js), a sideways drag still scrolls the rail. */
.hc-kids-week__open {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-kids-week__open:active .hc-kids-week__title { opacity: 0.7; }
.hc-kids-week__cal {
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-left: 6px;
  vertical-align: -2px;
}
.hc-kids-cal__head { justify-content: center; margin-top: var(--hc-space-sm); }
.hc-kids-cal__label { min-width: 9em; }
.hc-kids-week__title { margin-top: 6px; }
.hc-kids-week__passage { margin-top: var(--hc-space-xs); color: var(--hc-mid); }

.hc-kids-idea {
  margin-top: var(--hc-space-lg);
  padding: var(--hc-card-pad);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-cream);
  border-left: 4px solid var(--hc-gold);
  text-align: center;
}

.hc-kids-idea__text {
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: calc(21px * var(--hc-text-scale));
  line-height: 1.3;
  color: var(--hc-ink);
}

.hc-kids-section { margin-top: var(--hc-section-top); }
.hc-kids-section > .hc-section-header { margin-top: 0; }

/* Read aloud, so a step bigger than the body type and a little looser. */
.hc-kids-story {
  font-family: var(--hc-serif);
  font-size: calc(18px * var(--hc-text-scale));
  line-height: 1.6;
  color: var(--hc-ink);
}

.hc-kids-story + .hc-kids-story { margin-top: var(--hc-space-base); }

.hc-kids-prayer { font-style: oblique 8deg; }

/* ---- what changes with the group ---- */

.hc-kids-nudge {
  padding: var(--hc-space-base);
  border-radius: var(--hc-radius-lg);
  border: 1px dashed var(--hc-rule);
  text-align: center;
  font-family: var(--hc-serif);
  font-style: oblique 8deg;
  color: var(--hc-mid);
}

.hc-kids-block + .hc-kids-block { margin-top: var(--hc-space-lg); }
.hc-kids-block__eyebrow { margin-bottom: var(--hc-space-sm); }
.hc-kids-block > .hc-section-header { margin-top: 0; }

.hc-kids-questions { list-style: none; margin: 0; padding: 0; }

.hc-kids-question {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: var(--hc-space-md);
  align-items: start;
  padding: var(--hc-space-md) 0;
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-kids-question__n {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--hc-radius-pill);
  background: var(--hc-cream);
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: 15px;
  color: var(--hc-accent-deep);
}

.hc-kids-question__text {
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: 1.5;
  padding-top: 3px;
}

.hc-kids-activity {
  padding: var(--hc-card-pad);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-cream);
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: 1.5;
}

/* ---- the checklist and the prize ---- */

.hc-kids-reward {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--hc-space-md);
  align-items: start;
  padding: var(--hc-space-base);
  border-radius: var(--hc-radius-lg);
  background: var(--hc-paper-sunk);
  transition: background var(--hc-dur-base) var(--hc-ease);
}

.hc-kids-reward__star svg {
  width: 36px;
  height: 36px;
  color: var(--hc-gold);
  transition: fill var(--hc-dur-base) var(--hc-ease);
}

.hc-kids-reward__text {
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-body-serif) * var(--hc-text-scale));
  line-height: 1.5;
  color: var(--hc-ink);
}

.hc-kids-reward[data-done="true"] {
  background: color-mix(in srgb, var(--hc-gold) 26%, var(--hc-cream));
}

.hc-kids-reward[data-done="true"] .hc-kids-reward__star svg { fill: var(--hc-gold); }

.hc-kids-checks { margin-top: var(--hc-space-md); }

.hc-kids-check {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--hc-space-md);
  align-items: center;
  width: 100%;
  min-height: 60px;
  padding: var(--hc-space-md) 0;
  text-align: left;
  border-top: var(--hc-hairline) solid var(--hc-rule);
}

.hc-kids-check:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }

.hc-kids-check__box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: 1.5px solid var(--hc-rule);
  transition: background var(--hc-dur-fast) var(--hc-ease),
              border-color var(--hc-dur-fast) var(--hc-ease);
}

.hc-kids-check__tick {
  width: 20px;
  height: 20px;
  stroke: var(--hc-on-dark);
  stroke-width: 2.4;
  opacity: 0;
  transition: opacity var(--hc-dur-fast) var(--hc-ease);
}

.hc-kids-check__text {
  font-family: var(--hc-serif);
  font-size: calc(var(--hc-question) * var(--hc-text-scale));
  line-height: 1.4;
  color: var(--hc-ink);
}

.hc-kids-check[aria-pressed="true"] .hc-kids-check__box {
  background: var(--hc-success);
  border-color: var(--hc-success);
}

.hc-kids-check[aria-pressed="true"] .hc-kids-check__tick { opacity: 1; }

.hc-kids-progress { margin-top: var(--hc-space-md); text-align: center; }

.hc-kids-saved {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--hc-space-xs);
  margin-top: var(--hc-space-xs);
  color: var(--hc-success);
}

.hc-kids-saved[hidden] { display: none; }
.hc-kids-saved__icon { width: 16px; height: 16px; flex: none; }

.hc-kids-show { margin-top: var(--hc-space-base); }

/* ---- for parents, for volunteers ---- */

.hc-kids-parent-note { margin-bottom: var(--hc-space-base); }

.hc-kids-update__title {
  font-family: var(--hc-serif);
  font-weight: 500;
  font-size: calc(19px * var(--hc-text-scale));
  line-height: 1.3;
}

.hc-kids-update__when { margin-bottom: var(--hc-space-xs); }
.hc-kids-update__summary { margin-top: var(--hc-space-sm); }

.hc-kids-update__details {
  margin: var(--hc-space-sm) 0 0;
  padding-left: 1.1em;
  font-family: var(--hc-serif);
  font-size: calc(15px * var(--hc-text-scale));
  line-height: 1.5;
  color: var(--hc-ink);
}

.hc-kids-update__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hc-space-xs) var(--hc-space-base);
  margin-top: var(--hc-space-sm);
}

.hc-kids .hc-section { margin-top: var(--hc-section-top); }

/* ---- the card a family shows the teacher ---- */

.hc-kids-teacher {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(env(safe-area-inset-top) + var(--hc-space-lg)) var(--hc-screen-pad)
           calc(env(safe-area-inset-bottom) + var(--hc-space-lg));
  background: var(--hc-overlay);
  animation: hc-kids-fade var(--hc-dur-base) var(--hc-ease-enter);
}

@keyframes hc-kids-fade { from { opacity: 0; } to { opacity: 1; } }

.hc-kids-teacher__card {
  position: relative;
  width: 100%;
  max-width: 420px;
  max-height: 100%;
  overflow-y: auto;
  padding: var(--hc-space-xl) var(--hc-card-pad) var(--hc-space-lg);
  border-radius: 20px;
  background: var(--hc-paper);
  box-shadow: var(--hc-shadow-modal);
  text-align: center;
}

.hc-kids-teacher__card[data-done="true"] {
  background: color-mix(in srgb, var(--hc-gold) 18%, var(--hc-paper));
}

.hc-kids-teacher__close {
  position: absolute;
  top: var(--hc-space-sm);
  right: var(--hc-space-sm);
  width: var(--hc-tap-min);
  height: var(--hc-tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--hc-mid);
}

.hc-kids-teacher__close svg { width: 22px; height: 22px; }

.hc-kids-teacher__title {
  margin-top: var(--hc-space-sm);
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: 26px;
  line-height: 1.2;
  color: var(--hc-ink);
}

.hc-kids-teacher__name {
  display: block;
  margin-top: var(--hc-space-base);
  text-align: left;
}

.hc-kids-teacher__name .hc-input { margin-top: var(--hc-space-xs); text-align: center; }

.hc-kids-teacher__list {
  list-style: none;
  margin: var(--hc-space-lg) 0 0;
  padding: 0;
  text-align: left;
}

.hc-kids-teacher__item {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: var(--hc-space-md);
  align-items: center;
  padding: var(--hc-space-sm) 0;
  font-family: var(--hc-serif);
  font-size: 17px;
  line-height: 1.35;
  color: var(--hc-mid);
}

.hc-kids-teacher__item[data-on="true"] { color: var(--hc-ink); }

.hc-kids-teacher__mark svg {
  width: 28px;
  height: 28px;
  color: var(--hc-rule);
}

.hc-kids-teacher__item[data-on="true"] .hc-kids-teacher__mark svg {
  color: var(--hc-gold);
  fill: var(--hc-gold);
}

.hc-kids-teacher__count {
  margin-top: var(--hc-space-lg);
  font-family: var(--hc-sans-display);
  font-weight: 800;
  font-size: 44px;
  line-height: 1;
  color: var(--hc-ink);
}

.hc-kids-teacher__foot { margin-top: var(--hc-space-sm); }

/* The monthly report: the same card, a month at a time. */
.hc-kids-report__month {
  display: grid;
  grid-template-columns: var(--hc-tap-min) 1fr var(--hc-tap-min);
  align-items: center;
  margin-top: var(--hc-space-xs);
}

.hc-kids-report__month .hc-kids-teacher__title { margin-top: 0; }

.hc-kids-report__span { margin-top: 2px; }

.hc-kids-report__week {
  margin-top: var(--hc-space-lg);
  padding-top: var(--hc-space-base);
  border-top: 1px solid var(--hc-rule);
  text-align: left;
}

.hc-kids-report__week .hc-kids-teacher__list { margin-top: var(--hc-space-xs); }

.hc-kids-report__lesson {
  margin-top: 2px;
  font-family: var(--hc-serif);
  font-weight: 500;
  font-size: 19px;
  line-height: 1.3;
  color: var(--hc-ink);
}

.hc-kids-report__tally { margin-top: 2px; }
.hc-kids-report__week[data-done="true"] .hc-kids-report__tally { color: var(--hc-ink); }

.hc-kids-report__pdf { margin-top: var(--hc-space-lg); width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .hc-kids-teacher { animation: none; }
}

/* Admin -> HomeKids: the whole drafted guide, folded under its card. */
.hc-admin__preview { margin-top: var(--hc-space-sm); }
.hc-admin__preview > summary { cursor: pointer; color: var(--hc-accent-deep); min-height: var(--hc-tap-min); display: flex; align-items: center; }
.hc-admin__preview .hc-eyebrow { margin-top: var(--hc-space-md); }
.hc-admin__preview .hc-caption + .hc-caption { margin-top: var(--hc-space-xs); }

/* ==========================================================================
   Coffee, the Happy Lion Cafe. js/screens/cafe.js.
   Built from the same cards, eyebrows and buttons as everything else, with
   the cafe's own logo at the top in place of a photograph.
   ========================================================================== */

.hc-cafe__logo { width: 150px; margin: 0 auto; color: var(--hc-ink); }
.hc-cafe__logo img,
.hc-cafe__logo svg { display: block; width: 100%; height: auto; aspect-ratio: 180 / 216; }
.hc-cafe__logo--small { width: 110px; }
/* The logo is one colour, drawn in ink. On the dark theme it is drawn in the
   dark theme's ink instead, which is the same picture inverted. */
:root[data-theme="dark"] .hc-cafe__logo img { filter: invert(1) brightness(0.95); }

.hc-cafe__open { text-align: center; margin: var(--hc-space-md) 0 0; }
.hc-cafe__dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--hc-success); margin-right: var(--hc-space-sm); vertical-align: 1px;
}
.hc-cafe__dot--off { background: var(--hc-warning); }
.hc-cafe__lede { margin: 0 0 var(--hc-space-base); }
.hc-cafe__more { text-align: center; margin-top: var(--hc-space-lg); }

.hc-cafe-mine, .hc-cafe-counter { margin-top: var(--hc-space-base); display: flex; flex-direction: column; gap: 4px; }
.hc-cafe-mine__line { font: 500 17px/22px var(--hc-serif); color: var(--hc-ink); }

/* Drinks and Food, each under a header that folds it away. The header is
   the serif of a drink's name, a size up, with the section chevron's turn:
   pointing down while open, to the right while folded. */
.hc-cafe-part + .hc-cafe-part { margin-top: var(--hc-space-md); }
.hc-cafe-part__head { margin: var(--hc-space-base) 0 var(--hc-space-sm); }
.hc-cafe-part__toggle {
  display: flex; align-items: center; justify-content: space-between; gap: var(--hc-space-sm);
  width: 100%; min-height: var(--hc-tap-min); padding: 0;
  background: none; border: 0; border-bottom: var(--hc-hairline) solid var(--hc-rule);
  color: var(--hc-ink); font: 500 24px/30px var(--hc-serif); letter-spacing: -0.01em;
  text-align: left; cursor: pointer;
}
.hc-cafe-part__chev { flex: none; width: 22px; height: 22px; color: var(--hc-mid); transition: transform 0.2s ease; }
.hc-cafe-part__toggle[aria-expanded="false"] .hc-cafe-part__chev { transform: rotate(-90deg); }
.hc-cafe-part__items[hidden] { display: none; }
/* The milk choice has no group heading over it, so it keeps the heading's
   distance from the sizes above instead. */
.hc-cafe-seg + .hc-cafe-opts { margin-top: 22px; }
@media (prefers-reduced-motion: reduce) { .hc-cafe-part__chev { transition: none; } }

/* A drink on the menu. */
.hc-cafe-item { display: flex; align-items: center; gap: 14px; }
.hc-cafe-item[aria-disabled="true"] { opacity: 0.6; }
.hc-cafe-item__art {
  flex: none; width: 64px; height: 64px; border-radius: 10px; display: grid; place-items: center;
  background: var(--hc-paper); border: var(--hc-hairline) solid var(--hc-rule); color: var(--hc-ink);
}
.hc-cafe-item__icon { width: 34px; height: 34px; }
.hc-cafe-item__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hc-cafe-item__name { font: 500 19px/24px var(--hc-serif); letter-spacing: -0.01em; }
.hc-cafe-item__price { font: 400 14px/20px var(--hc-sans); color: var(--hc-mid); margin-top: 2px; }
.hc-cafe-item__add {
  flex: none; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  background: var(--hc-dark); color: var(--hc-on-dark); font: 400 22px/1 var(--hc-sans);
}

/* The bar that says what is in the order, beside the menu button. */
.hc-cafe-cartbar {
  position: fixed; z-index: 44;
  left: var(--hc-screen-pad);
  right: calc(var(--hc-navfab-size) + var(--hc-chrome-inset) * 2);
  bottom: calc(var(--hc-chrome-inset) + env(safe-area-inset-bottom) + 6px);
  height: 52px; padding: 0 var(--hc-space-base);
  display: flex; align-items: center; gap: var(--hc-space-sm);
  border-radius: var(--hc-radius-md); background: var(--hc-dark); color: var(--hc-on-dark);
  font: 600 var(--hc-button)/var(--hc-button-line) var(--hc-sans);
  box-shadow: var(--hc-shadow-modal);
}
#app[data-nav="bar"] .hc-cafe-cartbar {
  right: var(--hc-screen-pad);
  bottom: calc(var(--hc-tabbar-h) + env(safe-area-inset-bottom) + var(--hc-space-md));
}
/* The bar sits in the row the way up disc uses, and is the thing being asked
   on this screen, so while it is there the disc stands down, the same as it
   does for Note this / Highlight (#app[data-hlbar]). The menu is one short
   screen; there is little to go back up to. */
#app:has(.hc-cafe-cartbar) .hc-disc--top {
  opacity: 0;
  transform: translateY(10px) scale(0.86);
  pointer-events: none;
}
.hc-cafe-cartbar__n {
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  background: var(--hc-on-dark); color: var(--hc-dark); font-size: 13px;
}
.hc-cafe-cartbar__label { flex: 1; text-align: left; }

/* The drink's sheet. On <body>, over the chrome, under the toast. */
.hc-cafe-sheet { position: fixed; inset: 0; z-index: 58; }
.hc-cafe-sheet__scrim { position: absolute; inset: 0; background: var(--hc-overlay); border: 0; padding: 0; width: 100%;
  animation: hc-cafe-fade var(--hc-dur-base) var(--hc-ease); }
.hc-cafe-sheet__panel {
  position: absolute; left: 0; right: 0; bottom: 0; max-height: 92vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--hc-paper); color: var(--hc-ink);
  border-radius: 16px 16px 0 0; box-shadow: var(--hc-shadow-sheet);
  padding: 10px var(--hc-screen-pad) calc(var(--hc-space-lg) + env(safe-area-inset-bottom));
  animation: hc-cafe-up var(--hc-dur-sheet) var(--hc-ease-enter);
}
.hc-cafe-sheet[data-settled="true"] .hc-cafe-sheet__panel,
.hc-cafe-sheet[data-settled="true"] .hc-cafe-sheet__scrim { animation: none; }
@keyframes hc-cafe-up { from { transform: translateY(30%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes hc-cafe-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .hc-cafe-sheet__panel, .hc-cafe-sheet__scrim { animation: none; }
}
.hc-cafe-sheet__grab { width: 36px; height: 4px; border-radius: 2px; background: var(--hc-rule); margin: 0 auto 14px; }
.hc-cafe-sheet__title {
  font: 500 var(--hc-display-m)/var(--hc-display-m-line) var(--hc-serif);
  letter-spacing: -0.015em; margin: 4px 0 2px;
}
.hc-cafe-sheet__blurb { margin: 0; }
html.hc-cafe-sheet-open, html.hc-cafe-sheet-open body { overflow: hidden; }

.hc-cafe__label {
  display: block; margin: 22px 0 10px;
  font: 600 var(--hc-eyebrow)/var(--hc-eyebrow-line) var(--hc-sans);
  letter-spacing: var(--hc-track-eyebrow); text-transform: uppercase; color: var(--hc-accent-deep);
}
.hc-cafe__label--gap { margin-top: 28px; }

.hc-cafe-seg {
  display: flex; padding: 3px; gap: 3px; border-radius: var(--hc-radius-md);
  background: var(--hc-paper-sunk); border: var(--hc-hairline) solid var(--hc-rule);
}
.hc-cafe-seg__opt {
  flex: 1; min-height: var(--hc-tap-min); padding: 8px 0; border-radius: var(--hc-radius-sm);
  font: 500 15px/20px var(--hc-sans); color: var(--hc-mid); display: flex; flex-direction: column; align-items: center;
}
.hc-cafe-seg__opt span { font-weight: 400; font-size: 12px; line-height: 16px; }
.hc-cafe-seg__opt[aria-checked="true"] { background: var(--hc-paper); color: var(--hc-ink); box-shadow: 0 1px 3px rgba(26,25,24,0.12); }
:root[data-theme="dark"] .hc-cafe-seg__opt[aria-checked="true"] { background: var(--hc-cream); }

.hc-cafe-opt {
  display: flex; align-items: center; gap: var(--hc-space-md); min-height: 54px; flex-wrap: wrap;
  border-top: var(--hc-hairline) solid var(--hc-rule); padding: 6px 0;
}
.hc-cafe-opts .hc-cafe-opt:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }
.hc-cafe-opt__name { flex: 1; min-width: 90px; font: 400 var(--hc-body-sans)/22px var(--hc-sans); display: flex; flex-direction: column; }
.hc-cafe-opt__name small { color: var(--hc-mid); font-size: 13px; line-height: 18px; }
.hc-cafe-levels { display: flex; gap: 4px; flex-wrap: wrap; }
.hc-cafe-level {
  min-height: 36px; padding: 0 10px; border-radius: var(--hc-radius-pill);
  border: var(--hc-hairline) solid var(--hc-rule); font: 500 13px/1 var(--hc-sans); color: var(--hc-mid);
}
.hc-cafe-level[aria-checked="true"] { background: var(--hc-dark); border-color: var(--hc-dark); color: var(--hc-on-dark); }
.hc-cafe-step { display: flex; align-items: center; gap: var(--hc-space-md); }
.hc-cafe-step b { font: 600 16px var(--hc-sans); min-width: 14px; text-align: center; }
.hc-cafe-step__btn {
  width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  border: var(--hc-hairline) solid var(--hc-rule); background: var(--hc-cream);
  font: 400 18px/1 var(--hc-sans); color: var(--hc-ink);
}
.hc-cafe-step__btn[disabled] { color: var(--hc-rule); }

.hc-cafe-wide.hc-btn { display: flex; width: 100%; justify-content: space-between; margin-top: 22px; }

/* Your order. */
.hc-cafe-lines { margin-top: var(--hc-space-base); }
.hc-cafe-line { display: flex; gap: var(--hc-space-md); padding: 14px 0; border-top: var(--hc-hairline) solid var(--hc-rule); }
.hc-cafe-line:last-child { border-bottom: var(--hc-hairline) solid var(--hc-rule); }
.hc-cafe-line__body { flex: 1; min-width: 0; }
.hc-cafe-line__name { font: 500 17px/22px var(--hc-serif); }
.hc-cafe-line__mods { font: 400 13px/18px var(--hc-sans); color: var(--hc-mid); margin-top: 2px; }
.hc-cafe-line__price { font: 500 16px/22px var(--hc-sans); }
.hc-cafe-line__edit { display: flex; gap: 6px; margin-top: 4px; color: var(--hc-accent-deep); font: 600 13px var(--hc-sans); }
.hc-cafe-line__edit button { min-height: 32px; color: var(--hc-accent-deep); font: inherit; }
.hc-cafe-line__edit span { line-height: 32px; }
.hc-cafe-addmore { margin-top: var(--hc-space-sm); min-height: var(--hc-tap-min); font: 600 14px var(--hc-sans); color: var(--hc-accent-deep); }

.hc-cafe-pickup { width: 100%; box-sizing: border-box; }
.hc-cafe-name { width: 100%; box-sizing: border-box; }
.hc-cafe-totals { margin-top: 22px; }
.hc-cafe-totals > div { display: flex; justify-content: space-between; font: 400 15px/26px var(--hc-sans); color: var(--hc-mid); }
.hc-cafe-totals .hc-cafe-totals__big { color: var(--hc-ink); font-weight: 600; font-size: 17px; }
.hc-cafe-error { margin: var(--hc-space-md) 0 0; color: var(--hc-error); font: 500 14px/20px var(--hc-sans); }
.hc-cafe-hint { margin-top: var(--hc-space-sm); text-align: center; }
.hc-cafe-square { margin-top: var(--hc-space-sm); text-align: center; }
.hc-cafe-note { margin-top: var(--hc-space-lg); }
.hc-cafe-signin { margin-top: var(--hc-space-lg); }
.hc-cafe-signin .hc-body-serif { margin: 0 0 var(--hc-space-md); }
.hc-cafe-actions { display: flex; flex-direction: column; gap: var(--hc-space-sm); margin-top: var(--hc-space-lg); }

/* The ticket. */
.hc-cafe-ticket { margin-top: 18px; text-align: center; padding: 26px var(--hc-card-pad); }
.hc-cafe-ticket__big {
  font: 800 54px/1 var(--hc-sans-display); letter-spacing: -0.02em; margin: 10px 0 8px;
}
.hc-cafe-ticket__big--words { font-size: 26px; line-height: 32px; }
.hc-cafe-ticket__when { margin: 0; }
.hc-cafe-ticket--ready { box-shadow: inset 0 0 0 1.5px var(--hc-success); }
.hc-cafe-track { list-style: none; display: flex; padding: 0; margin: 26px 4px 0; }
.hc-cafe-track__s { flex: 1; position: relative; text-align: center; font: 500 12px/16px var(--hc-sans); color: var(--hc-mid); }
.hc-cafe-track__s::before {
  content: ""; display: block; position: relative; z-index: 1;
  width: 14px; height: 14px; margin: 0 auto 8px; border-radius: 50%;
  border: 1.5px solid var(--hc-rule); background: var(--hc-cream); box-sizing: border-box;
}
.hc-cafe-track__s::after {
  content: ""; position: absolute; top: 6px; left: -50%; width: 100%; height: 1.5px; background: var(--hc-rule);
}
.hc-cafe-track__s:first-child::after { display: none; }
.hc-cafe-track__s.is-done { color: var(--hc-ink); }
.hc-cafe-track__s.is-done::before { background: var(--hc-success); border-color: var(--hc-success); }
.hc-cafe-track__s.is-done::after { background: var(--hc-success); }
.hc-cafe-track__s.is-now::before { box-shadow: 0 0 0 4px rgba(95,115,85,0.2); }

/* The counter. */
.hc-cafe-stats { display: flex; gap: var(--hc-space-sm); margin-top: var(--hc-space-base); }
.hc-cafe-stat { flex: 1; background: var(--hc-cream); border-radius: var(--hc-radius-lg); padding: 12px 14px; }
.hc-cafe-stat b { display: block; font: 800 26px/1.1 var(--hc-sans-display); }
.hc-cafe-stat span { font: 400 12px/16px var(--hc-sans); color: var(--hc-mid); }
.hc-cafe-pause { margin-top: var(--hc-space-base); }
.hc-cafe-pause .hc-row__body, .hc-cafe-pause .hc-row__label { display: flex; flex-direction: column; flex: 1; }
.hc-cafe-pause .hc-switch-row__sub { margin-top: 2px; }
.hc-cafe-grp {
  display: flex; justify-content: space-between; margin: 22px 0 0;
  font: 600 var(--hc-eyebrow)/var(--hc-eyebrow-line) var(--hc-sans);
  letter-spacing: var(--hc-track-eyebrow); text-transform: uppercase; color: var(--hc-mid);
}
.hc-cafe-tick { background: var(--hc-cream); border-radius: var(--hc-radius-lg); padding: var(--hc-space-base); margin-top: 10px; }
.hc-cafe-tick--making { border-left: 3px solid var(--hc-warning); border-top-left-radius: 4px; border-bottom-left-radius: 4px; }
.hc-cafe-tick--ready { border-left: 3px solid var(--hc-success); border-top-left-radius: 4px; border-bottom-left-radius: 4px; }
.hc-cafe-tick__top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--hc-space-sm); }
.hc-cafe-tick__who { font: 600 18px/24px var(--hc-sans); }
.hc-cafe-tick__no { font: 600 13px var(--hc-sans); color: var(--hc-accent-deep); }
.hc-cafe-tag {
  display: inline-block; vertical-align: 2px; margin-left: 6px; padding: 4px 7px; border-radius: var(--hc-radius-pill);
  background: var(--hc-paper); color: var(--hc-warning);
  font: 600 10px/1 var(--hc-sans); letter-spacing: 0.1em; text-transform: uppercase;
}
.hc-cafe-tick--ready .hc-cafe-tag { color: var(--hc-success); }
.hc-cafe-tick__d { list-style: none; margin: 10px 0 0; padding: 0; font: 400 15px/22px var(--hc-sans); }
.hc-cafe-tick__d small { display: block; color: var(--hc-mid); font-size: 13px; line-height: 18px; margin-bottom: 4px; }
.hc-cafe-tick__a { display: flex; gap: var(--hc-space-sm); margin-top: var(--hc-space-md); }
.hc-cafe-tick__a .hc-btn { flex: 1; }
.hc-btn.hc-cafe-readybtn { background: var(--hc-success); border-color: var(--hc-success); color: #FFFFFF; }
.hc-cafe-undo { margin-top: var(--hc-space-sm); min-height: 32px; font: 600 13px var(--hc-sans); color: var(--hc-accent-deep); }
.hc-cafe-done {
  display: flex; justify-content: space-between; align-items: center; padding: 8px 0;
  border-bottom: var(--hc-hairline) solid var(--hc-rule); font: 400 15px var(--hc-sans); color: var(--hc-mid);
}
.hc-cafe-done button { min-height: 32px; font: 600 13px var(--hc-sans); color: var(--hc-accent-deep); }

/* Open or closed, under the logo on Coffee and at the top of the queue.
   Green and red are the system's own success and error, which keep their
   contrast on both themes. */
.hc-cafe-status {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: fit-content; margin: var(--hc-space-base) auto 0;
  padding: 10px 18px; border-radius: var(--hc-radius-pill);
  font: 700 18px/22px var(--hc-sans); letter-spacing: 0.01em;
}
.hc-cafe-status__dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }
.hc-cafe-status--open { color: var(--hc-success); background: rgba(95,115,85,0.12); }
.hc-cafe-status--open .hc-cafe-status__dot { background: var(--hc-success); box-shadow: 0 0 0 4px rgba(95,115,85,0.22); }
.hc-cafe-status--closed { color: var(--hc-error); background: rgba(139,74,63,0.10); }
.hc-cafe-status--closed .hc-cafe-status__dot { background: var(--hc-error); box-shadow: 0 0 0 4px rgba(139,74,63,0.18); }
:root[data-theme="dark"] .hc-cafe-status--open { color: #9DB58F; background: rgba(157,181,143,0.14); }
:root[data-theme="dark"] .hc-cafe-status--open .hc-cafe-status__dot { background: #9DB58F; }
:root[data-theme="dark"] .hc-cafe-status--closed { color: #D9897A; background: rgba(217,137,122,0.14); }
:root[data-theme="dark"] .hc-cafe-status--closed .hc-cafe-status__dot { background: #D9897A; }
.hc-cafe-status + .hc-cafe__open { margin-top: var(--hc-space-sm); }

/* The counter's Open and Closed, two big buttons. */
.hc-cafe-oc { display: flex; gap: var(--hc-space-sm); margin-top: var(--hc-space-md); }
.hc-cafe-oc__btn {
  flex: 1; min-height: 52px; border-radius: var(--hc-radius-md);
  border: 1px solid var(--hc-rule); background: var(--hc-paper);
  font: 700 17px/1 var(--hc-sans); color: var(--hc-mid);
}
.hc-cafe-oc__btn--open[aria-pressed="true"] { background: var(--hc-success); border-color: var(--hc-success); color: #FFFFFF; }
.hc-cafe-oc__btn--closed[aria-pressed="true"] { background: var(--hc-error); border-color: var(--hc-error); color: #FFFFFF; }
.hc-cafe-oc__btn[disabled] { opacity: 0.6; }

.hc-cafe-counter__queue {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  min-height: var(--hc-tap-min); margin-top: var(--hc-space-sm);
  font: 500 17px/22px var(--hc-serif); color: var(--hc-ink);
}
.hc-cafe-counter__chev { width: 20px; height: 20px; color: var(--hc-mid); }
.hc-cafe-pause { padding-top: var(--hc-space-xs); }
.hc-cafe-pause > .hc-cafe-status { margin-top: 0; }
.hc-cafe-pause__note { margin-top: var(--hc-space-sm); text-align: center; }
.hc-cafe-oc__note { margin: var(--hc-space-sm) 0 0; text-align: center; }
.hc-cafe-oc__back { font: inherit; font-weight: 600; color: var(--hc-accent-deep); text-decoration: underline; min-height: 32px; }
