/* Peppy responsive layer - tablet and desktop.
 *
 * Loaded last, after peppy-theme.css, so it wins ties on source order and needs
 * almost no !important.
 *
 * THE ONE RULE IN THIS FILE: every declaration lives inside a `min-width` query
 * of 651px or more. Nothing here may reach a phone. The Capacitor Android build
 * ships these same files into a WebView that is always narrower than that, so a
 * rule written outside a query is a change to the shipped app, not to the web
 * version. 651px rather than 700px so the band abuts the existing
 * `max-width:650px` blocks in peppy.css and mobile-fixes.css exactly - a gap
 * between the two would be a stretch of widths with neither layer applying.
 *
 * The bands:
 *   <= 650px   phone     the design's 430px frame, untouched
 *   651-1023   tablet    one wider column, tab bar stays a bottom pill
 *   >= 1024px  desktop   left sidebar, and sub-pages open as a right pane
 *
 * Why this works at all: nearly every row in the renderers is an inline
 * `grid-template-columns: <fixed icon rail> minmax(0,1fr)`, which already
 * stretches. Widening the column reflows the app without touching a renderer.
 */

/* =============================================== legacy chrome, all bands == */

/* peppy.css still carries the 2023 prototype's chrome - a `.sidebar` header and
   a `.topbar-actions` row with the account line, Sign out and a `＋ Add`
   button. The theme replaced all of it (the brand row, the greeting card, the
   tab bar, Sign out under More > Profile), and index.html:61 and :69 already
   say so: both elements carry the `hidden` attribute.
   `hidden` is only a UA-stylesheet `display:none`, so ANY author rule outranks
   it - and peppy.css:5 `.sidebar{display:flex}` and peppy.css:26
   `.topbar-actions{display:flex}` both do. Under 650px that never showed,
   because the phone blocks in peppy.css and mobile-fixes.css were hiding the
   pieces anyway (mobile-fixes.css:446 and :470, peppy.css:118 and :151). Those
   blocks stop at 650px, so above it the prototype header reappears - an empty
   75px bar, then the account email and two buttons duplicating controls the
   theme puts elsewhere.
   So the fix is to let `hidden` mean hidden, rather than to hide the children:
   an attribute selector on top of the class outranks the bare class, and if
   app.js ever removes the attribute the element correctly reappears. Scoped to
   these two rather than written as a blanket `[hidden]{display:none!important}`
   reset, because on a phone peppy.css:144 deliberately shows `.sidebar` while
   the landing screen is up, and a blanket rule would be a change to the shipped
   Android build. */
@media (min-width: 651px) {
  .sidebar[hidden],
  .topbar-actions[hidden] { display: none; }

  /* peppy.css:19 `.content{max-width:850px}` is from the same prototype. The
     theme neutralised that rule's padding and margins but not its width cap, so
     the app silently stopped growing at 850px however wide the shell was told
     to be - a 1180px frame with an 850px column inside it and a band of dead
     canvas down the right. */
  body.peppy-theme .content { max-width: none; }
}

/* ============================================================== tablet == */

@media (min-width: 651px) {
  :root {
    /* Fill the window, less a small margin, up to 1180px. Two numbers doing two
       jobs: the `100% - 32px` makes a tablet edge-to-edge apart from a hairline
       of canvas, and the 1180px ceiling stops a 27in monitor stretching a row
       to a metre wide. Percentages here resolve against the viewport for both
       consumers - .p-shell's containing block is the body, and .p-drawer is
       position:fixed - so the sheet stays aligned with the app.
       The width is only useful because the lists below flow into it. A single
       620px column was the first cut of this and read as a phone that had been
       pulled slightly wider, which is the worst of both. */
    --p-shell-w: min(100% - 32px, 1180px);
  }

  /* The design's 20px side padding was set against a 390px frame. Held at 620px
     it reads as no margin at all, because the ratio is what the eye judges. */
  body.peppy-theme .p-body { padding-left: 28px; padding-right: 28px; }
  body.peppy-theme .p-head { padding-left: 28px; padding-right: 28px; }
  body.peppy-theme .p-brandbar { padding-left: 28px; padding-right: 28px; }

  /* The pill is a five-column grid filling the shell, so at 620px the tabs
     drift to the far edges with a void in the middle. Cap it and centre it -
     the bar is a control, not a header, and does not want to be full-bleed. */
  body.peppy-theme .p-tabbar-inner {
    max-width: 430px;
    margin: 0 auto;
  }

  /* A phone frame sits flush against the screen edge, so the design gives it no
     outer border. Floating on a canvas it needs one, or it reads as content
     that failed to fill the window rather than as a deliberate column. */
  body.peppy-theme .p-shell {
    box-shadow: 0 0 0 1px #dfeae7, 0 18px 60px #1434301a;
  }

  /* ------------------------------------------------------ flowing lists -- */

  /* A list that stays one column in a 1180px frame is the thing that makes a
     widened app look wrong: a row of 40 characters with 900px of white beside
     it, repeated down the page. These containers wrap left to right instead and
     start a new row when they run out, so the width buys more list on screen
     rather than more empty space.
     auto-FILL, not auto-fit: auto-fit collapses the empty tracks, so a filtered
     library showing one result would stretch that single card the full width -
     the exact stretching this is here to stop. auto-fill leaves the tracks in
     place and the card keeps its column.
     The 300px floor is the narrowest a row can be and still fit an icon tile,
     a compound name and its category label without wrapping the label. Below
     651px none of this applies and the lists stay the design's single column. */
  .p-flow {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--p-flow-min, 300px), 1fr));
    align-content: start;
    /* Wider than the row gap on purpose. A vertical stack has a shared left
       edge to read down, so items can sit close without running together;
       side-by-side cards have no such cue and need a clear channel between them
       or they read as one block. */
    column-gap: var(--p-flow-col-gap, 18px);
  }

  /* The ceiling on a card's width, and it has to sit on the item rather than on
     the track. It is tempting to write the track as
     `minmax(--p-flow-min, --p-flow-max)`, but auto-fill counts its repetitions
     from the MAX track sizing function whenever that is a definite length - so
     `minmax(340px, 540px)` in a 1084px column asks for 540px columns, fits one,
     and produces a single stretched card. Leaving the track at 1fr keeps the
     count coming from the min, and the cap goes on what sits in the track.
     Why cap at all: a card drawn for a 390px phone has its art, padding and
     type sized for that. At 600px on an ultrawide it stops reading as a card -
     the mascot strands itself at one end and the text runs the full width.
     justify-self keeps the capped card centred in its track instead of leaving
     all the slack down one side. */
  .p-flow > * { max-width: var(--p-flow-max, none); justify-self: center; width: 100%; }

  /* A heading inside a flowing container is a label for the whole group, not an
     item in it. As a plain grid child it takes the first cell and the first row
     of the list sits beside it, which reads as the heading being one of the
     options. These are every heading element the groups actually use. */
  .p-flow > .p-eyebrow,
  .p-flow > .p-section-head,
  .p-flow > h1,
  .p-flow > h2,
  .p-flow > h3 { grid-column: 1 / -1; }

  /* The library. !important is unavoidable here and only here: peppy-theme.css
     :1551 sets `display:flex !important` to outrank the legacy `column-count`
     declarations in peppy.css, and an !important can only be beaten by another.
     The legacy rules it was fighting are all inside `max-width:650px` blocks, so
     nothing else in that stack is live at this width. */
  body.peppy-theme #compound-cards {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    /* The gap needs restating, and it needs to be !important, for a reason that
       is not obvious. mobile-fixes.css:243 sets `column-gap:18px !important` on
       .compound-cards at EVERY width - it is not inside a media query - as part
       of a legacy `column-count:3` multi-column layout. peppy-theme.css:1584
       neutralises it with `column-gap:normal !important`, which was harmless
       while the list was a flex column, because column-gap does nothing there.
       In a grid, `normal` computes to 0, so the cards touched edge to edge.
       One `gap` shorthand sets both axes and outranks that reset on the id. */
    gap: 18px !important;
  }
  /* Same ceiling as .p-flow gets, applied here because #compound-cards is not
     one - it keeps its own grid rule to outrank the legacy !important stack. */
  body.peppy-theme #compound-cards > * { max-width: 460px; justify-self: center; width: 100%; }

}

/* ============================================================= desktop == */

/* The phone frame becomes an application window: navigation down the left, the
   current page in the middle, and a sub-page opening as a third column on the
   right instead of sliding over the top of everything.
 *
 * Nothing is re-rendered to do this. .p-shell is already a flex container whose
 * children are, in source order, the (hidden) legacy sidebar, .content,
 * #subpage and .p-tabbar. Turning the shell into a row and pulling the tab bar
 * to the front with `order` produces the three columns directly, so every view
 * and every sub-page arrives in the new layout without its renderer knowing.
 * That is also why the pane squeezes rather than overlays: #subpage stops being
 * position:absolute and becomes an ordinary flex item, so .content simply gets
 * less room while it is open and all of it back when it closes.
 */

@media (min-width: 1024px) {
  :root {
    /* Edge to edge. The tablet band floats the app as a card on a canvas, which
       works while it is a single column but stops working the moment there is a
       sidebar: an application window inset inside a browser window reads as a
       screenshot of an app rather than as the app. Every desktop product this
       resembles - a mail client, an admin console - runs its navigation into
       the corner of the viewport. */
    --p-shell-w: 100%;
    --p-sidebar-w: 248px;
    /* Wide enough for the sub-page forms, which were drawn for a 390px phone
       and have a lot of full-width inputs. Narrower and the labels wrap. */
    --p-pane-w: 460px;
    /* One scale for the whole desktop layout, so a card on Home and a card on
       Library are the same object rather than two arbitrary numbers.
       --p-measure is the widest a column of prose or a form should get. */
    --p-card: 420px;
    --p-measure: 560px;
    /* The width the calendar was drawn at. 430 less six 5px gutters is seven
       57px day squares - the size they are on a phone, give or take. */
    --p-cal-w: 430px;
  }

  /* ------------------------------------------------------------- frame -- */

  body.peppy-theme .p-shell {
    flex-direction: row;
    align-items: stretch;
    /* Undo the tablet band's floating-card treatment. */
    box-shadow: none;
  }

  /* .content and #subpage are the two that share what the sidebar leaves.
     min-width:0 on both, or a wide grid child refuses to shrink and pushes the
     pane off the right-hand edge - the flex default is min-width:auto.
     margin-block:0 is not tidying. peppy.css:19 sets `.content{margin:auto}`,
     and peppy-theme.css:145 zeroes only the left and right of it, because in a
     column shell those were the cross axis. Turning the shell into a row makes
     the cross axis vertical, so the surviving `margin-top/bottom:auto` centres
     the whole page in the window - 593px of content floating in an 880px frame
     with the header nowhere near the top. An auto margin beats align-items,
     so this has to be zeroed rather than aligned around. */
  body.peppy-theme .content {
    flex: 1 1 auto;
    min-width: 0;
    margin-block: 0;
  }

  /* ----------------------------------------------------- tab bar -> nav -- */

  /* The sidebar is a surface, not a floating control.
     This was the single thing most responsible for the desktop layout reading
     as unfinished: .p-tabbar-inner is a white rounded pill with a lifted
     shadow, because on a phone it floats over the content. Stood on its end and
     stretched to the full height it became a tall white capsule with five items
     at the top and six hundred pixels of empty white below them - a mobile tab
     bar wearing a sidebar's dimensions.
     So the panel moves outward: the column itself takes the white and a hairline
     against the canvas, the way a navigation rail is drawn, and the pill inside
     it gives up its background, its shadow and its stretch. */
  body.peppy-theme .p-tabbar {
    position: static;
    order: -1;
    flex: 0 0 var(--p-sidebar-w);
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 22px 14px;
    /* !important only to outrank peppy-theme.css:1073, which forces the wrapper
       transparent so the floating pill is the only thing that paints. */
    background: var(--p-surface) !important;
    border-right: 1px solid var(--p-line-2);
    /* The floating bar sets pointer-events:none on the wrapper so taps fall
       through to the content it overlaps. A sidebar overlaps nothing. */
    pointer-events: auto;
  }

  body.peppy-theme .p-sidebar-brand { display: block; padding: 2px 10px 0; }
  /* 128, not the 116 the flat SVG wore. This wordmark is 2.43:1 against that
     one's 3.18:1 and its letterforms are rounder and heavier, so at the same
     width it reads smaller than it measures. */
  body.peppy-theme .p-sidebar-brand img { display: block; width: 128px; height: auto; }

  /* Natural height, not flex:1 - the nav ends where its items end. */
  body.peppy-theme .p-tabbar-inner {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    gap: 2px;
    height: auto;
    flex: 0 0 auto;
    max-width: none;
    margin: 0;
    padding: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  body.peppy-theme .p-tab {
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    height: 46px;
    padding: 0 14px;
    border-radius: 14px;
    font-size: 13px;
    text-align: left;
  }
  body.peppy-theme .p-tab svg { width: 20px; height: 20px; }

  /* The honesty note at the foot of the sidebar.
     margin-top:auto is what puts it there: .p-tabbar is a column flex and the
     nav above it is flex:0 0 auto, so the auto margin takes all the leftover
     height and the note sits on the floor of the column however few tabs there
     are. Nothing is positioned absolutely, so it can never overlap the nav on a
     short window - it just stops being pushed down. */
  body.peppy-theme .p-sidebar-note {
    display: grid;
    grid-template-columns: 18px minmax(0, 1fr);
    align-items: start;
    gap: 10px;
    margin-top: auto;
    padding: 13px 14px;
    border: 1px solid var(--p-line-2);
    border-radius: 16px;
    background: var(--p-mint-faint);
    color: var(--p-muted-2);
  }
  body.peppy-theme .p-sidebar-note svg { width: 18px; height: 18px; color: var(--p-teal); }
  body.peppy-theme .p-sidebar-note strong {
    display: block;
    margin-bottom: 3px;
    color: var(--p-head);
    font-size: 12px;
    font-weight: 900;
  }
  body.peppy-theme .p-sidebar-note p {
    margin: 0;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.45;
    text-wrap: pretty;
  }

  /* ------------------------------------------------- sub-page as a pane -- */

  /* Read by app.js to decide whether the swipe-to-dismiss gesture applies. The
     breakpoint is declared once, here, and the script asks the element what it
     is rather than carrying its own copy of 1024 to drift out of step. */
  body.peppy-theme .p-subpage { --p-subpage-mode: pane; }

  body.peppy-theme .p-subpage {
    position: static;
    flex: 0 0 var(--p-pane-w);
    min-width: 0;
    /* The slide-over drew this to suggest a page floating above another. As a
       column it is a seam between two panes, so it wants the opposite: a hard
       edge, no spread. */
    box-shadow: none;
    border-left: 1px solid var(--p-line-2);
  }

  /* -------------------------------------------------- the reading column -- */

  /* One column, one left edge. The page header and the page body take the same
     padding so the title sits directly above the content it names - the thing
     that most makes a page look composed rather than assembled.
     Padding rather than max-width: the scroller stays the full width of the
     pane, so its scrollbar sits at the window edge where it is expected instead
     of floating in the middle of the page. The pane is narrow and needs none of
     this. */
  body.peppy-theme .content .p-body,
  body.peppy-theme .content .p-head {
    padding-left: max(40px, calc((100% - 1180px) / 2));
    padding-right: max(40px, calc((100% - 1180px) / 2));
  }

  /* The page header. It was carrying phone spacing - a 24px title 6px above the
     content, which at this size reads as a stray line rather than a heading. */
  body.peppy-theme .content .p-head { padding-top: 26px; padding-bottom: 18px; }
  body.peppy-theme .content .p-head h1 { font-size: 27px; }

  /* ------------------------------------------------ drawer as a panel -- */

  /* The compound record, the record editor and the cycle sheet all rise from
     the bottom of the phone frame. Left alone they would inherit
     `max-width: var(--p-shell-w)` and become a 1520px-wide sheet climbing the
     whole window. They become a panel down the right instead - the same place
     the sub-page pane sits, so "detail about the thing you just clicked" always
     arrives from the same edge.
     They stay modal, with the backdrop: they are aria-modal, they trap Escape,
     and several of them are editors with unsaved state. */
  body.peppy-theme .p-drawer { --p-drawer-mode: panel; }

  body.peppy-theme .p-drawer {
    left: auto;
    /* Against the app's right edge, not the window's, so it lines up with the
       shell on a monitor wide enough for the 1520px cap to bite. */
    right: max(24px, calc((100% - var(--p-shell-w)) / 2 + 24px));
    top: 24px;
    bottom: 24px;
    width: min(520px, 42vw);
    max-width: none;
    border-radius: 26px;
    /* Off to the right rather than below. The extra 40px carries the shadow off
       screen with it, which a plain 100% leaves smeared down the edge. */
    transform: translate3d(calc(100% + 40px), 0, 0);
  }
  body.peppy-theme .p-drawer.is-open { transform: translate3d(0, 0, 0); }

  /* The 20px + safe-area was clearance for the floating tab bar, which is a
     sidebar here and nowhere near it. */
  body.peppy-theme .p-drawer [data-drawer-body] { padding-bottom: 20px; }

  /* ------------------------------------------------------- page layouts -- */

  /* Each page gets a layout, rather than every page getting the same width cap.
     The first attempt at this tiled whatever it found with auto-fill, and the
     result read as unfinished for a reason worth writing down: auto-fill makes
     no distinction between a card, a heading and a control, so a page came out
     as a mosaic of whatever happened to be in it at whatever height it happened
     to be. A layout has to know what the blocks ARE. */

  /* --- Home: a dashboard ------------------------------------------------- */

  /* Two columns under a full-width greeting. The plan and the cycles are what
     the page is for and take the wide side; the stat row and the streak card
     comment on them and take the narrow one. This is the arrangement every
     dashboard converges on because it matches how the page is read - primary
     down the left, at-a-glance down the right - and it is only possible because
     the five blocks now carry names (index.html:83-129) instead of being five
     anonymous divs the grid had to guess at. */
  body.peppy-theme .content > [data-app-view="home"] > .p-body {
    display: grid;
    grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr);
    grid-auto-flow: row dense;
    align-content: start;
    column-gap: 22px;
  }
  body.peppy-theme .p-home-hero { grid-column: 1 / -1; }
  body.peppy-theme .p-home-plan,
  body.peppy-theme .p-home-cycles { grid-column: 1; }
  body.peppy-theme .p-home-stats,
  body.peppy-theme .p-home-nudge { grid-column: 2; }

  /* --- pages that own their own stack ------------------------------------ */

  /* Library, More, Calendar and Analysis keep a single column, because each has
     furniture that is not a card - a mascot banner, a search field, a button, a
     view switcher - and standing those in columns beside the content is what
     made the first attempt look broken.
     The furniture is held to a readable measure. It gains nothing from the full
     width: a search box the width of a window is not easier to use, and a
     banner that wide strands its mascot at one end. */
  body.peppy-theme .content > [data-app-view="calendar"] > .p-body > *,
  body.peppy-theme .content > [data-app-view="analysis"] > .p-body > *,
  body.peppy-theme .content > [data-app-view="compounds"] > .p-body > *,
  body.peppy-theme .content > [data-app-view="more"] > .p-body > * { max-width: var(--p-measure); }

  /* And these are let back through, because they are the parts that genuinely
     earn the width: a chip strip shows every filter instead of scrolling, and
     the lists tile. */
  body.peppy-theme .content > .app-view > .p-body > .p-chips,
  body.peppy-theme .content > .app-view > .p-body > .p-flow,
  body.peppy-theme .content > .app-view > .p-body > #compound-cards { max-width: none; }

  /* --- Calendar: dates at their own size, the day beside them ------------- */

  /* A day cell is `aspect-ratio:1` (app.js:1330, :1353), so its width sets its
     height. Letting the grid have the full 1072px therefore did not produce a
     roomy calendar - it produced seven 153px squares and a month five hundred
     pixels tall, which is what made this page look broken. The calendar is a
     fixed-size object, like a date picker: it is held at the width it was drawn
     for, and the space that buys goes to the day's plan standing next to it. */
  body.peppy-theme .content > [data-app-view="calendar"] > .p-body > * { max-width: var(--p-cal-w); }
  body.peppy-theme .content > [data-app-view="calendar"] > .p-body > .calendar-grid { max-width: none; }

  /* Three declarations need !important, for the same reason each time.
     mobile-fixes.css carries a set of UNSCOPED rules - outside any media query,
     despite the file's name - that still describe the 2023 calendar:
       .calendar-grid[data-mode="week"|"month"|"day"] { display:block!important }
       .calendar-grid[data-mode="month"] { grid-template-columns:repeat(7,minmax(0,1fr))!important; gap:6px!important }
     The first flattens this rule's grid; the second is why the month view alone
     came out as two 148px slivers while the week view was already correct - my
     two columns were being placed in the first two of seven. An !important can
     only be answered by another. align-items lands normally, unclaimed. */
  /* Week and month only. Day mode has no calendar to stand beside - it renders
     the agenda alone (app.js:1306) - so it stays a single column. */
  body.peppy-theme #calendar-grid[data-mode="week"],
  body.peppy-theme #calendar-grid[data-mode="month"] {
    display: grid !important;
    grid-template-columns: minmax(0, var(--p-cal-w)) minmax(0, var(--p-measure)) !important;
    column-gap: 30px !important;
    align-items: start;
  }
  /* Holds the day's plan to a readable measure in all three modes. */
  body.peppy-theme .p-cal-detail { max-width: var(--p-measure); }
  /* The heading carries a 14px top margin to separate it from the dates it sits
     under. Beside them instead, that margin is what stops the two columns
     starting on the same line. */
  body.peppy-theme #calendar-grid .p-cal-detail > :first-child { margin-top: 0; }

  /* ------------------------------------------------------- scroll bars -- */

  /* A phone hides every scrollbar, which is right - it is furniture nobody
     asked for on a touchscreen. With a mouse it is the only thing telling you
     there is more below, and its absence reads as a page that has ended.
     The scroller is .app-view.active, NOT .p-body. peppy-theme.css:1482 puts
     `overflow-y:auto` on the view and :1517 then forces every direct child of
     it to `flex:0 0 auto; overflow:visible !important`, so the body is a plain
     block inside a scrolling view. Styling .p-body here, as this first did,
     dresses an element that never scrolls and leaves the desktop with no
     scrollbar at all.
     The chip strips keep theirs hidden - there a scrollbar is genuinely noise
     beside a row of pills. */
  body.peppy-theme .app-view.active,
  body.peppy-theme .p-subpage {
    scrollbar-width: thin;
    scrollbar-color: #c3ddd7 transparent;
  }
  body.peppy-theme .app-view.active::-webkit-scrollbar,
  body.peppy-theme .p-subpage::-webkit-scrollbar {
    display: block;
    width: 10px;
    height: 10px;
  }
  body.peppy-theme .app-view.active::-webkit-scrollbar-thumb,
  body.peppy-theme .p-subpage::-webkit-scrollbar-thumb {
    border: 3px solid transparent;
    border-radius: 99px;
    background: #c3ddd7;
    background-clip: content-box;
  }

  /* The page title stays put while its content scrolls. On a phone the header
     scrolls away because the screen is short and every pixel is wanted for
     content; on a desktop a title that leaves the moment you scroll a long
     library is the thing that makes a page feel like a document rather than an
     application. The canvas background is not decoration - without it the rows
     would show through as they pass underneath. */
  body.peppy-theme .content .p-head {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--p-canvas);
  }

  /* ------------------------------------------------- pointer affordances -- */

  /* A keyboard ring. The app has almost none, because a phone has no tab key.
     Worth promoting out of this band eventually - :focus-visible only fires for
     keyboard interaction, so it would cost a touch user nothing - but that
     would be a change to the shipped Android build and belongs in its own
     pass. */
  body.peppy-theme .p-shell :focus-visible,
  body.peppy-theme .p-drawer :focus-visible {
    outline: 2px solid var(--p-teal);
    outline-offset: 2px;
  }
}

/* ------------------------------------------------- the landing screen -- */

/* The first thing a signed-out visitor sees, and until now the one screen with
   no desktop treatment at all: a 400px ribbon of content down the middle of a
   1440px gradient. It becomes the two-column split a marketing page wants -
   what Peppy is on the left, how to get in on the right - without touching the
   markup, by placing the five existing children on an explicit grid.
   Kept at 1024px, the same breakpoint as the sidebar, so a visitor never sees
   the app in one layout and the door to it in another. */
@media (min-width: 1024px) {
  /* Named areas rather than line numbers, because the wordmark spans both
     columns and the sign-in card spans three rows - written as coordinates that
     is four rules nobody can read, and one of them has to change whenever a row
     is added. */
  body.peppy-theme .landing-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    grid-template-areas:
      "logo    logo"
      "hero    actions"
      "pillars actions"
      "note    actions";
    column-gap: 64px;
    row-gap: 20px;
    align-content: center;
    justify-content: center;
    max-width: 1120px;
    margin: 0 auto;
    padding: 56px 48px;
  }

  /* Across both columns and centred on them, so the mark sits over the whole
     screen rather than over the left half of it. The theme already gives it
     `margin: 0 auto`; the wider area is what lets that centre against
     everything instead of against one column. */
  body.peppy-theme .landing-logo { grid-area: logo; width: 176px; margin: 0 auto 10px; }

  body.peppy-theme .landing-hero { grid-area: hero; }
  body.peppy-theme .landing-pillars { grid-area: pillars; }
  body.peppy-theme .landing-note { grid-area: note; }

  /* The sign-in column: a real card, because it is the one thing on this screen
     being asked for and it should look like the destination rather than like
     two buttons that ran out of page.
     align-self:start, not center. Centred against three rows it floated at its
     own height, level with nothing - the eye reads two cards side by side and
     expects their top edges to agree. Starting it lines it up with the hero
     card's top edge and keeps it there however long the copy gets. */
  body.peppy-theme .landing-actions {
    grid-area: actions;
    align-self: start;
    align-content: start;
    gap: 12px;
    padding: 34px 30px;
    border-radius: 26px;
    background: var(--p-surface);
    box-shadow: var(--p-shadow-card);
  }

  /* 30ch was a measure for a phone column; the card is twice that wide here.
     The `auto` is load-bearing and was the bug: `margin: 0` alone left a 345px
     paragraph pinned to the left edge of a 540px card, so its text was centred
     within a box that was itself sitting off to one side - which reads as
     nothing being aligned to anything. */
  body.peppy-theme .landing-sub { margin: 0 auto; max-width: 46ch; }
}

@media (min-width: 1024px) and (hover: hover) {
  body.peppy-theme .p-tab:not(.is-active):hover {
    background: var(--p-mint-faint);
    color: var(--p-teal-deep);
  }
  /* Every tappable surface in the app, so a mouse gets the same "this responds"
     signal a finger gets from the press state. Transform rather than a shadow
     change: it composites, so a list of 66 cards does not repaint on hover. */
  body.peppy-theme .p-card:hover,
  body.peppy-theme .p-row:hover,
  body.peppy-theme [data-compound-id]:hover,
  body.peppy-theme [data-more-action]:hover {
    transform: translateY(-1px);
    cursor: pointer;
  }
  body.peppy-theme .p-card,
  body.peppy-theme .p-row,
  body.peppy-theme [data-compound-id],
  body.peppy-theme [data-more-action] {
    transition: transform .14s ease;
  }
}

@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
  body.peppy-theme .p-card,
  body.peppy-theme .p-row,
  body.peppy-theme [data-compound-id],
  body.peppy-theme [data-more-action] { transition: none; }
  body.peppy-theme .p-card:hover,
  body.peppy-theme .p-row:hover,
  body.peppy-theme [data-compound-id]:hover,
  body.peppy-theme [data-more-action]:hover { transform: none; }
}
