/* 05-dash-layout.css. How those parts are arranged on body.dash: the folding cards, the
   bordered tile boxes, the 12 column grid, and the other apps menu. */

/* ==========================================================================
   The dashboard's own layout. Parchment, like the rest of the app.
   ==========================================================================

   Eric, 2026-08-20, holding four real dashboards next to this page: "those are
   what dashboards look like. your dashboard looks like [craigslist]." The thing
   worth taking from those references was never the dark ground, which he said
   plainly afterwards. It was the shape: one number per box at a size you can
   read across a room, the change against last period stated beside it rather
   than left to be worked out, and the reading starting immediately instead of
   after a paragraph explaining it.

   So this is that shape on the parish's own parchment. Scoped to body.dash, so
   the entry forms keep their quieter treatment.
*/
body.dash .card { padding: 1.1rem 1.2rem 1.3rem; }
body.dash .card h2 {
  font-size: var(--step-1);
  letter-spacing: -0.01em;
  margin-bottom: 0.8rem;
}
body.dash .card h3 {
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted);
  margin: 1.5rem 0 0.6rem;
}

/* A CARD THAT FOLDS, on a phone and nowhere else.

   The Offertory tab carries three cards where every other tab carries one, and
   at 390px it ran to 6,638px, near eight phone screens. Measured on
   2026-08-22: the three cards are 69% of that, and the tiles, which were the
   suspect, are 21%. Laying the tiles two across was built and measured and
   saved 455px of 6,638 while dropping every figure from 36px to 26px, so the
   column count was never the problem. The tab was.

   So the Mass Collection, the parish's own number and the only one on this tab
   somebody types, stays open, and the two records beside it fold.

   Two of these exist and both are on one tab. That is deliberate: a card that
   folds and has nothing to fold beside it is the lone half card again, and a
   rule with no user is how this stylesheet has hurt before.

   ABOVE THE BREAKPOINT THERE IS NO CONTROL. The summary is not a pointer
   target, carries no caret, and reads exactly as the h2 it replaced, because
   the script never closes a card at that width and a control that does nothing
   is worse than no control. */
details.foldable > summary { list-style: none; }
details.foldable > summary::-webkit-details-marker { display: none; }
/* The h2 owns the card's top edge either way, so its own bottom margin would
   double the gap when the card is open and hang below the title when it is
   shut. The gap belongs to whatever follows the summary. */
body.dash details.foldable > summary h2 { margin-bottom: 0; }
body.dash details.foldable > summary + * { margin-top: 0.8rem; }

@media (max-width: 40rem) {
  body.dash details.foldable > summary {
    cursor: pointer;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
  }
  /* A WORD, not only a caret. At this size the glyph is about eight pixels of
     pale grey against a card title, which says "there is a whole card folded in
     here" to nobody. The word says it, and it is emerald because emerald is
     what this site's actions and links are. The tap target is the whole
     <summary> row, not this. */
  body.dash details.foldable > summary::after {
    content: "Show \25be";
    font-size: var(--step--1);
    font-weight: 600;
    line-height: 1;
    color: var(--emerald);
    white-space: nowrap;
    flex: none;
  }
  body.dash details.foldable[open] > summary::after { content: "Hide \25b4"; }
  /* Shut, the card is a title and a Show, so its foot has no content to sit
     under and the top padding is all the room it needs at the bottom too. */
  body.dash details.foldable:not([open]) { padding-bottom: 1.1rem; }
}

/* One number per box, and the box is visible. A tile row was borderless text at
   1.7rem, which reads as a paragraph with some bold in it. */
/* Flex, not grid, and every tile may grow. A grid track count is fixed by the
   container width, so five tiles in a four wide row left the fifth stranded on a
   line of its own beside an empty half of the card. Flex items stretch to fill
   the row they land on, so a row is always a row. */
body.dash .tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 0.4rem;
}
/* 7.5rem, not 11.5rem. At 18pt root a 11.5rem basis is 276px, so four tiles
   wanted 1,100px inside a card about 780px wide: three sat on the first row and
   the fourth stretched across the second on its own, which is the stranded box
   again in a different shape. Flex still grows them to fill whatever row they
   land on. */
/* Wide enough for a money figure at the size above. Four across on a full
   screen, and they still grow to fill whatever row they land on. */
body.dash .tile { flex: 1 1 10rem; }
/* WHITE on the parchment ground with a coloured edge, rather than parchment on
   parchment. Eric, 2026-08-21, pointing at the Service System's counters: the
   tile reads as an object sitting on the page instead of a lighter patch of it,
   and the edge says what KIND of number it is before the number is read.
   The colour is meaning, never decoration: emerald for a figure where rising is
   good, amber for one that wants a look, red for one that wants an answer
   today, navy for a plain count with no direction to it. */
body.dash .tile {
  background: #fff;
  border: 1px solid var(--line);
  border-left: 4px solid var(--navy);
  border-radius: 6px;
  /* TIGHTER THAN IT WAS, and this is the whole of item 10. Eric, 2026-08-22:
     "Too much space for the individual numbers in the top section. and the line
     and bar charts are burried below. the speacing is bad."
     A tile row cost about 150 to 180px and Work orders drew two of them, so on
     a laptop the first chart began below the fold on a tab whose point is the
     trend. Nothing is removed and no figure is smaller than the scale allows:
     the padding, the label gap and the note leading each give back a few pixels
     and together they are worth roughly a third of the row.
     The figure steps DOWN one, from step-3/step-4 to step-2/step-3. It is still
     the largest thing in the tile by a wide margin, which is what makes it read
     as the figure. Run scripts/check_phone.py after touching any of this: the
     value is nowrap, so a figure too big for its box leaves the card rather
     than wrapping, and that check is the only thing that says so (D43). */
  padding: 0.6rem 0.85rem 0.7rem;
  min-width: 0;
}
body.dash .tile:has(.tile-value.up),
body.dash .tile:has(.tile-value.fell) { border-left-color: var(--emerald); }
body.dash .tile:has(.tile-value.down),
body.dash .tile:has(.tile-value.rose) { border-left-color: var(--warn); }
/* Nothing in it yet is not a state worth colouring. */
body.dash .tile:has(.tile-empty) { border-left-color: var(--line); }
body.dash .tile-label {
  font-size: var(--step--2);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.2;
  color: var(--muted);
  margin-bottom: 0.25rem;
}
body.dash .tile-value {
  font-size: clamp(var(--step-2), 3.4vw, var(--step-3));
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--navy);
  white-space: nowrap;
}
body.dash .tile-note {
  font-size: var(--step--2);
  line-height: 1.35;
  color: var(--muted);
  margin-top: 0.25rem;
}
/* A second tile row's own label. Only Work orders has one: its first row is
   point-in-time ("as of the last read") and its second is processed over weeks,
   which is a real distinction and the reason they are two rows rather than one.
   Full h3 weight between them cost about 40px and read as a new section rather
   than as a caption on the row underneath. The adjacent-sibling selector is
   what keeps this off every other h3 on the page: nowhere else does a heading
   directly follow a tile row. */
body.dash .tiles + h3 {
  margin: 0.55rem 0 0.35rem;
  font-size: var(--step--2); text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); font-weight: 600;
}

body.dash .tile-empty { font-size: var(--step-0); color: var(--muted); font-style: italic; }
body.dash .tile-value.up { color: var(--emerald); }
body.dash .tile-value.down { color: var(--danger); }
/* The arrow is drawn, not typed into every template.
   up and down are for a figure where rising is the good direction: attendance,
   giving. rose and fell are for one where it is not, such as a queue of work
   orders getting longer. The ARROW follows the sign and the COLOUR follows
   whether it is good news, because an arrow pointing down beside "+1" is a
   sentence contradicting itself. */
body.dash .tile-value.up::before   { content: "\2191\00a0"; font-size: 0.80em; }
body.dash .tile-value.down::before { content: "\2193\00a0"; font-size: 0.80em; }
body.dash .tile-value.rose::before { content: "\2191\00a0"; font-size: 0.80em; }
body.dash .tile-value.fell::before { content: "\2193\00a0"; font-size: 0.80em; }
body.dash .tile-value.rose { color: var(--danger); }
body.dash .tile-value.fell { color: var(--emerald); }
/* The one that wants an answer today. Still white, so the row stays one family;
   the edge and the figure carry it. A filled red box beside four white ones is
   louder than the thing it is reporting. */
body.dash .tile.alarm { border-left-color: var(--danger); }
body.dash .tile.alarm .tile-label { color: var(--danger); }
body.dash .tile.alarm .tile-value { color: var(--danger); }

@media (max-width: 640px) {
  body.dash .tile-value { font-size: var(--step-3); }
}

/* Entering a number happens at the foot of the tab that shows it. Eric,
   2026-08-20: "the tabs need to have the data metrics at the top, and the bottom
   is where you can enter data. that's where it gets recorded." */
/* The way in, at the foot of every tab. A heading, a sentence and a button,
   stacked, used 57% of a 1,035px card on four separate tabs: the same
   "land a plane on that white space" shape Eric pointed at on This Week, on
   four more screens. scripts/check_fill.py found it, which is what that check
   was written for. The words go left, the action goes right, and they wrap to
   stacked below about 40rem where side by side would squeeze the button. */
.entrybox {
  border: 1px solid var(--line);
  border-top: 3px solid var(--emerald);
  border-radius: 6px;
  background: #fff;
  padding: 1rem 1.2rem;
  margin: 0 0 1rem;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.7rem 1.5rem;
}
.entrysay { flex: 1 1 26rem; min-width: 0; }
.entrybox > .button { flex: 0 0 auto; }
.entrybox h2 { font-size: var(--step-1); letter-spacing: -0.01em;
              margin-bottom: 0.2rem; }
.entrybox .lede { margin-bottom: 0; }
.entrybox table.entry { margin: 0 0 0.8rem; }
.entrybox .readonly {
  color: var(--muted);
  font-style: italic;
  margin: 0;
}
.entryrow { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: flex-end; }
.entryrow label { display: flex; flex-direction: column; gap: 0.25rem; margin: 0;
                  font-size: var(--step--1); color: var(--muted); }
.entryrow input, .entryrow select { min-width: 8rem; }

/* Modular, responsive boxes. Eric, 2026-08-20: "The boxes should be modular.
   they should be responsive."

   The dashboard's cards were a single column of full-width blocks, so a wide
   screen showed one card and a lot of empty page, and reading two things side by
   side meant scrolling between them. They sit in a twelve column grid now: a
   card claims half the width when its content holds up at that size, the whole
   width when it needs the room for a chart, and every card falls back to the
   full width on a narrow screen. Nothing here is a fixed pixel size, so the
   layout has no breakpoint it looks wrong just below. */
body.dash main {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1.1rem;
  align-content: start;
}
/* Headings, tabs, the gap strip and anything else that is not a box run the
   full width of the grid. */
body.dash main > *:not(.card):not(.entrybox) { grid-column: 1 / -1; }
body.dash main > .card,
body.dash main > .entrybox { grid-column: 1 / -1; margin-bottom: 0; }
/* `.half` USED TO LIVE HERE, span 6 of the 12, and it is gone with the two
   cards that carried it. It worked; it was never PAIRED. A half card only reads
   as a choice when a second one sits beside it, and both of the two on this site
   were alone, so the Offertory and Sacraments tabs each drew one box down the
   left with a column of empty parchment next to it. Eric found it by looking.

   Removed rather than left for later, because a rule with no user is how this
   stylesheet has hurt before: the palette reverted on 2026-08-20 left its dark
   pair behind and every chart spent a day at 1.53:1 against its own background.
   `scripts/check_layout.py` now measures every box on every tab and names any
   that is narrow with nothing beside it, so bringing this back WITH a partner is
   a safe change and bringing it back alone fails a check. */
@media (max-width: 48rem) {
  main { width: auto; max-width: none; padding-left: 1rem; padding-right: 1rem; }
  body.wide main { width: auto; max-width: none; }
}

/* The other St. Edward apps, from the masthead. A details element, so it opens
   with no script and closes with Escape, and it sits in the bar rather than on a
   page, because the reason to leave for one of them can arrive on any screen. */
.appsmenu { position: relative; }
.appsmenu > summary {
  list-style: none;
  cursor: pointer;
  color: #e9e6dd;
  border-bottom: 2px solid transparent;
  padding-bottom: 2px;
}
.appsmenu > summary::-webkit-details-marker { display: none; }
.appsmenu > summary::after { content: " \25be"; }
.appsmenu > summary:hover,
.appsmenu[open] > summary { color: #fff; border-bottom-color: var(--gold); }
.appsmenu > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.appsmenu ul {
  position: absolute;
  right: 0;
  top: calc(100% + 0.6rem);
  z-index: 30;
  min-width: 17rem;
  margin: 0;
  padding: 0.4rem;
  list-style: none;
  background: #fff;
  border: 1px solid var(--line);
  border-top: 3px solid var(--gold);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(20, 32, 46, 0.22);
}
.appsmenu li { display: flex; align-items: baseline; gap: 0.5rem; padding: 0.35rem 0.5rem; }
/* The panel is white and it sits inside <nav>, where `nav a` paints links the
   near-white that belongs on the navy bar. Without this the menu rendered white
   on white: the same defect as the brand, in the thing built to fix the brand.
   A link inside a panel takes the panel's colours, not the bar's. */
.appsmenu li a { color: var(--emerald); text-decoration: none; font-weight: 600; }
.appsmenu li a:hover, .appsmenu li a:focus-visible {
  color: var(--navy); text-decoration: underline;
}

/* On a phone the bar wraps, so the menu drops into the flow rather than floating
   off the right edge of a narrow screen. */
@media (max-width: 48rem) {
  .appsmenu ul { position: static; min-width: 0; box-shadow: none; margin-top: 0.4rem; }
}

