/* ============================================================================
   StratiLogger — Screen-level styles shared by BOTH orientations
   (landing page, column manager, print dialog)   —   FLEXY

   Orientation-specific positioning lives in shells/*.css. Anything here must
   work in landscape and portrait alike.
   ========================================================================== */

/* ============================================================================
   INTERFACE SIZE, OUTSIDE THE WORKSPACE
   shared/ui/settings.js · owner 5 Aug 2026: "cog item supposed to show setting:
   ui size, …"

   The workspace has zoomed its chrome by `--ui-scale` since 3 Aug
   (`shells/*.css`). The project browser and every dialog did not, because the
   control lived on `CL.App` and there is no App on the landing — so the first
   screen of the app was the one screen whose size could not be changed, which
   is a poor joke to play on somebody who set it larger because they cannot read
   the small one.

   `--chrome-zoom` is RELATIVE TO THE DEFAULT rung, not the raw scale. The
   ladder's default is 0.80 ('m'), and zooming these boxes by 0.80 would have
   shrunk every screen outside the workspace the moment this shipped, for a
   setting nobody had touched. Dividing by the default makes M mean 1 — no
   change at the default, and the six other rungs scale around it.

   Zoom lands on the CHILDREN rather than on `.landing`, for the reason
   `shells/*.css` puts it on `.topbar`/`.rail` and not on `.ws`: `zoom` scales a
   `height: 100%` box after it resolves, so a zoomed flex container would leave
   a strip of ground below itself at any size under 1.
   ========================================================================== */
:root { --chrome-zoom: calc(var(--ui-scale, 0.80) / 0.80); }
.landing__top, .landing__bar, .landing__sectionhead, .ptable, .pcards,
.dialog, .toast { zoom: var(--chrome-zoom, 1); }

/* ============================================================================
   LANDING / PROJECT BROWSER   —  sketch `0 landingpage.png`

   Three cards on the grey ground: the brand + actions header, the scrolling
   project list, the Import / Export bar. The card treatment itself is in
   tokens.css; only the composition is here.
   ========================================================================== */
.landing {
  display: flex; flex-direction: column;
  height: 100%; gap: var(--gap);
  /* The GROUND runs to the physical edge of the screen; the three cards stop
     at the safe area. On the web all four `--inset-*` are `0px` and this is
     exactly `padding: var(--gap)` — see the safe-area block in tokens.css. */
  padding:
    calc(var(--gap) + var(--inset-top))
    calc(var(--gap) + var(--inset-right))
    calc(var(--gap) + var(--inset-bottom))
    calc(var(--gap) + var(--inset-left));
  background: var(--ground);
  /* The anchor for `.syncbanner`, which floats above the Import/Export bar
     while the login mirror runs. */
  position: relative;
}
.landing__top {
  display: flex; align-items: center; gap: 14px 18px;
  padding: 18px var(--s-5); flex: none;
  /* WRAPS RATHER THAN CRUSHES. Flex does not refuse to fit — it compresses,
     and with `flex: 1` on the brand and `flex: none` on six controls the brand
     is what gives. At XXL interface size that meant the wordmark box arriving
     about 90 px wide, with "Digital core & outcrop logging" stacked one word
     per line underneath a logo the Create button was sitting on top of.
     Wrapping puts the controls on their own line instead, at every size. */
  flex-wrap: wrap;
}
/* The SedStrat mark sits beside the wordmark, so the first screen carries
   the same identity the workspace does. `min-width` is the floor the wrap
   above triggers at: narrower than this and the tagline starts breaking. */
.landing__brand {
  flex: 1 1 220px; min-width: 200px;
  display: flex; align-items: center; gap: var(--s-3);
}
.landing__mark { flex: none; display: inline-flex; line-height: 0; }
.landing__brandtext { min-width: 0; }
.landing__title {
  margin: 0; font: var(--t-display); color: var(--heading);
  letter-spacing: -.02em; border: 0; padding: 0; display: block;
}
.landing__tag { display: block; margin-top: 3px; font: var(--t-caption); color: var(--muted); }
.landing__actions {
  display: flex; align-items: center; gap: 10px; width: auto; flex: none;
  /* Among themselves too: five controls and a search box do not fit a phone in
     one row, and the alternative to wrapping is a twelve-pixel search field.

     `max-width` is what makes the wrap happen at all. A `flex: none` box sizes
     to its content and then simply overflows its parent — at XXL that put Sign
     out half off the right edge of the card, wrapping obediently at a width
     nothing was constraining. */
  flex-wrap: wrap; max-width: 100%; min-width: 0;
}
/* Who is signed in. Present only on a client that has sessions at all — the
   Android shell never signs in, so `capabilities.accounts` is false there and
   neither this nor the Sign out button is rendered (CLAUDE.md §2.7). */
.landing__who {
  font: var(--t-label); color: var(--muted);
  max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.landing__new { white-space: nowrap; }
.landing__search { width: 260px; text-align: left; }

/* Below 900 px the controls take the full width under the brand, and the
   search takes whatever the buttons leave. Nothing is hidden: portrait is a
   re-arrangement, never a reduction (docs/planning/06 §1). */
@media (max-width: 900px) {
  .landing__brand { flex: 1 0 100%; }
  .landing__actions { flex: 1 1 100%; }
  .landing__search { flex: 1 1 160px; width: auto; min-width: 140px; }
}

.landing__lists { flex: 1; min-height: 0; overflow-y: auto; padding: var(--s-2) 0 var(--s-4); }

.landing__sectionhead {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: var(--s-4) var(--s-5) 10px;
  font: var(--t-section); color: var(--heading);
  border: 0; margin: 0; text-align: left;
}
.landing__sectionhead--plain { font: var(--t-label); color: var(--muted); }
.landing__n { margin-left: auto; font: var(--t-caption); color: var(--muted); }

.landing__bar {
  display: flex; align-items: center; gap: 10px;
  padding: var(--s-3) var(--s-5); flex: none;
}
.landing__count { font: var(--t-label); color: var(--primary); }

/* ---- table (landscape) ------------------------------------------------- */
.ptable { padding: 0 var(--s-4); }
.prow {
  display: grid; align-items: center; gap: var(--s-3);
  /* The last track is the delete button (owner, 2 Aug 2026 — the browser
     listed projects it could not remove). */
  grid-template-columns: 30px minmax(140px, 2fr) 1fr 1.2fr 1.2fr 1fr 1fr 118px 30px;
  min-height: 40px; padding: 2px 8px;
  border-radius: var(--radius-1); cursor: pointer;
  border-bottom: var(--hairline) solid var(--border-2);
}

/* ---- THE TABLE HAS TO FIT THE SPACE IT IS GIVEN ------------------------------
   Owner, 5 Aug 2026: *"project list in landscape is broken. i did not see project
   list … make project list more compact, maybe table view."*

   Nine tracks — checkbox, six fields, Where, delete — with a 160 px floor on the
   name and a 14 px gap between each. That is roughly 420 px of fixed width before
   a single flexible column gets anything, and in landscape the list is competing
   with a 108 px tool rail and a 320 px panel. On a tablet there was nothing left:
   the columns crushed into each other and the rows read as empty.

   So the low-value columns drop out as the space narrows, in the order a
   geologist would give them up. Project and Modified are what the list is FOR;
   Where says whether it is on the tablet or the server; the delete button must
   never be the thing that disappears, because a row you cannot remove is the bug
   this table was fixed for once already.

   Column-count changes are made on BOTH the head and the body rows by the same
   query, so the header can never label a column the rows are not drawing. */
@media (max-width: 1200px) {
  .prow { grid-template-columns: 30px minmax(140px, 2fr) 1fr 1.2fr 1fr 62px 30px; }
  .prow__c--creator, .prow__c--created { display: none; }
}
@media (max-width: 900px) {
  .prow { grid-template-columns: 30px minmax(120px, 2fr) 1fr 62px 30px; }
  .prow__c--location, .prow__c--company { display: none; }
}
.prow:hover { background: var(--ground); }
.prow--head {
  cursor: default; font: 600 12px/16px var(--font-ui); color: var(--muted);
  border-bottom: var(--hairline) solid var(--border);
  position: sticky; top: 0; background: var(--card); z-index: 1;
}
.prow--head:hover { background: var(--card); }
.prow--head .prow__c { cursor: pointer; }
.prow__cb { display: flex; align-items: center; }
.prow__cb input { width: 17px; height: 17px; accent-color: var(--primary); }
.prow__name { display: flex; align-items: center; gap: var(--s-2); overflow: hidden; color: var(--heading); }
.prow__name b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow__c {
  font-size: 13.5px; color: var(--body);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.prow__where { font: var(--t-caption); color: var(--muted); text-align: right; }

/* ============================================================================
   THE SYNC CELL — one checkbox, one chip, one ring
   docs/planning/16-portability-sync.md §3-§4

   Owner, 5 Aug 2026: *"each project have sync checkbox … when sync checked,
   then synchronization process start (add progress ring)."*

   The chip is the state (⌂ ☁ ⇄ ⇄•), the box is the control, and the ring takes
   the box's PLACE while a transfer runs rather than sitting beside it — so the
   control is un-pressable during the transfer without a `disabled` attribute
   anybody has to notice.

   The label is drawn at every width in portrait and hidden below 1200 px in
   landscape, where the column is 92 px and the chip alone says it. Both are on
   `.synccell`, so the two layouts share one component and differ in CSS only.
   ========================================================================== */
.synccell {
  display: inline-flex; align-items: center; gap: 7px;
  justify-content: flex-end; white-space: nowrap; cursor: default;
}
.synccell__box {
  width: 17px; height: 17px; flex: none; margin: 0;
  accent-color: var(--primary); cursor: pointer;
}
/* ONE DOT, FOUR TONES (owner, 5 Aug 2026: "synced (green) · syncing (orange) ·
   sync queued (orange) · sync failed (red) · offline (blue)").
   The tone comes from `CL.sync.STATES[…].tone`, so shared logic never names a
   colour and this file stays the only place the palette is decided. */
.synccell__dot {
  flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--muted);
}
.synccell__label {
  font: var(--t-caption); color: var(--muted);
  overflow: hidden; text-overflow: ellipsis;
}
.synccell[data-tone="ok"]   .synccell__dot { background: var(--ok); }
.synccell[data-tone="busy"] .synccell__dot { background: var(--warn); }
.synccell[data-tone="bad"]  .synccell__dot { background: var(--danger); }
.synccell[data-tone="info"] .synccell__dot { background: var(--primary); }
/* Grey, and hollow: "Device only" is the absence of a sync rather than a state
   of one, and a filled grey dot in a column of coloured ones reads as a fifth
   status the user has to learn. */
.synccell[data-tone="idle"] .synccell__dot {
  background: transparent; box-shadow: inset 0 0 0 1.5px var(--border);
}
.synccell[data-tone="ok"]   .synccell__label { color: var(--body); }
.synccell[data-tone="bad"]  .synccell__label { color: var(--danger); }
.synccell.is-busy .synccell__label { color: var(--warn); }

/* THE TABLE GETS THE WORD WHERE THERE IS ROOM FOR IT.
   The column is 118 px, which fits a 17 px box, a dot and "Sync queued". Below
   1200 px two other columns have already dropped out and the row is tight, so
   the word goes and the dot and the tooltip carry it. */
@media (max-width: 1200px) {
  .prow .synccell__label { display: none; }
}

.syncring { flex: none; transform-origin: 50% 50%; }
.syncring__track { fill: none; stroke: var(--border); stroke-width: 2.5; }
.syncring__arc {
  fill: none; stroke: var(--primary); stroke-width: 2.5; stroke-linecap: round;
  /* Drawn from twelve o'clock rather than three, which is where a ring that
     fills clockwise is expected to start. */
  transform: rotate(-90deg); transform-origin: 50% 50%;
  transition: stroke-dashoffset .18s linear;
}
.syncring.is-indeterminate {
  animation: syncspin 1.1s linear infinite;
}
.syncring.is-indeterminate .syncring__arc { transition: none; }
@keyframes syncspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  /* A rotating ring is decoration; the fact that something is in progress is
     not. So the motion stops and the arc stays, which still reads as busy. */
  .syncring.is-indeterminate { animation: none; }
}

/* The banner over the project list while the login mirror runs. NOT a modal:
   collecting eleven bundles takes as long as it takes, and a scrim for the
   duration would make signing in feel like an install. */
.syncbanner {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s-5) + 56px); z-index: 40;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; border-radius: 999px;
  background: var(--card); color: var(--body);
  border: var(--hairline) solid var(--border);
  box-shadow: var(--shadow-2, 0 6px 24px rgba(0,0,0,.18));
  font: var(--t-label);
}
.syncbanner__text { white-space: nowrap; }

/* ---- cards (portrait) --------------------------------------------------- */
.pcards { padding: 0 var(--s-4) var(--s-3); display: flex; flex-direction: column; gap: 10px; }
.pcard {
  border: var(--hairline) solid var(--border); border-radius: var(--radius-2);
  padding: var(--s-4); background: var(--card); cursor: pointer;
}
.pcard:active { background: var(--ground); }
.pcard__l1 { display: flex; align-items: center; gap: 10px; }
.pcard__l1 input { width: 18px; height: 18px; accent-color: var(--primary); flex: none; }
.pcard__l1 b { flex: 1; color: var(--heading); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcard__where { font: var(--t-caption); color: var(--muted); }
.pcard__l2 { font-size: 13.5px; color: var(--body); margin-top: 5px; padding-left: 28px; }
.pcard__l3 {
  font: var(--t-caption); color: var(--muted); margin-top: 2px; padding-left: 28px;
  /* Two things on one line: who and when on the left, the sync control pushed
     to the right edge where the thumb reaches it. */
  display: flex; align-items: center; gap: 10px;
}
.pcard__l3 .synccell, .pcard__where { margin-left: auto; }

/* ============================================================================
   SETTINGS  —  the cog's destination on BOTH clients
   shared/ui/settings.js

   Owner, 5 Aug 2026: *"cog item supposed to show setting: ui size, server path,
   auto sync, offline mode only, etc.."*

   A list of groups, each a title and some rows; a row is a label and a control
   on one line with the explanation under it. The explanation is the point — a
   toggle called "Work offline only" needs a sentence saying what it stops, and
   there is no room for that sentence on the same line as the switch.
   ========================================================================== */
/* ---- the scale picker ----------------------------------------------------
   Owner, 5 Aug 2026: *"add more scale options: 1:5 - 1:5000.. even allow user to
   type them self."* The field sits above the ladder and holds only the second
   half of the ratio; the "1 :" beside it is the label, so the box is a number
   box and typing "1:250" into it still works (CL.parseScale). */
.dialog--scale { width: min(360px, 92vw); }
.scalefield {
  display: flex; align-items: center; gap: var(--s-2);
  padding: 14px 18px 6px;
}
.scalefield__lead { color: var(--muted); font-size: 15px; flex: none; }
.scalefield__input { flex: 1; min-width: 0; text-align: left; }

.dialog--settings { width: min(620px, 94vw); }
.dialog--about { width: min(480px, 94vw); }
.dialog--conflict { width: min(600px, 94vw); }

.settings { padding: var(--s-4) var(--s-5) var(--s-5); max-width: 620px; }
.setgroup + .setgroup { margin-top: var(--s-5); }
.setgroup__title {
  margin: 0 0 var(--s-2); font: var(--t-label); color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em;
}
/* ONE LINE PER SETTING: label left, control right, nothing under it.
   Owner, 5 Aug 2026: *"each option have explanation, remove the explanation.
   Just straight to the menu."* The row was label-over-hint with the control
   floated up beside the label; with the prose gone it is simply a row, and the
   padding tightens because there is no second line to breathe under. */
.setrow {
  display: flex; align-items: center; gap: var(--s-4);
  min-height: 44px; padding: 4px 0;
  border-bottom: var(--hairline) solid var(--border-2);
}
.setrow:last-child { border-bottom: 0; }
.setrow__label { flex: 1; min-width: 0; color: var(--heading); font-weight: 500; }
.setrow__pair { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.setrow__input { width: 260px; max-width: 40vw; font: var(--t-mono, 12px/1.4 monospace); }
.setrow__value {
  color: var(--body); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 24ch;
}

/* A switch rather than a checkbox for the two sync toggles, because they are
   settings that take effect immediately rather than choices confirmed later —
   the same distinction the Column Manager's Show / Printable boxes rely on in
   the other direction. */
.switch { position: relative; display: inline-flex; flex: none; cursor: pointer; }
.switch__input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch__track {
  width: 42px; height: 24px; border-radius: 999px;
  background: var(--border); transition: background .15s ease;
  display: inline-block; position: relative;
}
.switch__track::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.3);
  transition: transform .15s ease;
}
.switch__input:checked + .switch__track { background: var(--primary); }
.switch__input:checked + .switch__track::after { transform: translateX(18px); }
.switch__input:focus-visible + .switch__track { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ============================================================================
   ABOUT  —  its own layout, at last
   shared/ui/settings.js

   Owner, 5 Aug 2026: *"when sedstrat img clicked in working page, it pops up an
   about page. layout is not neat."*

   The old one borrowed `.checkrow__hint` for paragraphs and `.meta__pair` for
   facts, so it inherited a control's indent and a metadata header's label
   column — which is sized for "Hole ID" and therefore put "Website" on top of
   its own value. Nothing here is borrowed.
   ========================================================================== */
.about { padding: var(--s-4) var(--s-5) var(--s-5); max-width: 460px; }
.about__head { display: flex; align-items: center; gap: var(--s-4); margin-bottom: var(--s-4); }
.about__mark { flex: none; display: inline-flex; line-height: 0; }
.about__id { min-width: 0; }
.about__name { font: var(--t-display); color: var(--heading); letter-spacing: -.02em; }
.about__tag { margin-top: 2px; font: var(--t-caption); color: var(--muted); }
.about__p {
  margin: 0 0 var(--s-3); color: var(--body);
  font-size: 13.5px; line-height: 1.55; max-width: 46ch;
}
.about__facts {
  margin: var(--s-4) 0 0; padding-top: var(--s-4);
  border-top: var(--hairline) solid var(--border);
}
/* ONE label column, sized to the longest label, so a long value wraps under
   itself instead of colliding with its own key. */
.about__fact { display: grid; grid-template-columns: 84px 1fr; gap: var(--s-3); padding: 4px 0; }
.about__k { margin: 0; font: var(--t-caption); color: var(--muted); }
.about__v { margin: 0; font-size: 13px; color: var(--body); word-break: break-word; }
.about__v a { color: var(--primary); }

/* ============================================================================
   SYNC CONFLICT  —  Steam-style, with the project's own default
   docs/planning/16-portability-sync.md §6.1
   ========================================================================== */
.conflict { padding: var(--s-4) var(--s-5); max-width: 560px; }
.conflict__lead { margin: 0 0 var(--s-4); color: var(--body); font-size: 13.5px; line-height: 1.5; }
.conflict__sides { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
@media (max-width: 560px) { .conflict__sides { grid-template-columns: 1fr; } }
.conflict__side {
  display: flex; flex-direction: column; gap: 4px;
  padding: var(--s-4); border-radius: var(--radius-2);
  border: var(--hairline) solid var(--border); background: var(--ground);
}
.conflict__sidehead { font: var(--t-label); color: var(--heading); font-weight: 600; }
.conflict__when { font-size: 15px; color: var(--heading); }
.conflict__files { font: var(--t-caption); color: var(--muted); }
.conflict__note { font: var(--t-caption); color: var(--muted); margin-bottom: var(--s-3); flex: 1; }
/* Outlined, not bare. A ghost button on a tinted panel reads as a caption —
   and these two are the whole choice the dialog is asking for. */
.conflict__side .btn {
  width: 100%; justify-content: center;
  border: var(--hairline) solid var(--border); background: var(--card);
}
.conflict__side .btn:hover { border-color: var(--primary); color: var(--primary); }
.conflict__hint { margin: var(--s-4) 0 0; font: var(--t-caption); color: var(--muted); }
/* Sits to the LEFT of the footer buttons, so the default action's consequence
   is read on the way to pressing it. */
.conflict__default {
  font: var(--t-caption); color: var(--muted);
  max-width: 40ch; white-space: normal; text-align: left; margin-right: auto;
}

/* ============================================================================
   COLUMN MANAGER   —  sketch `4 column manager.png`
   ========================================================================== */
.dialog--cm { width: min(1080px, 96vw); height: min(760px, 88vh); }
.dialog--layers { width: min(560px, 96vw); height: min(700px, 84vh); }
.dialog--print { width: min(1000px, 96vw); height: min(700px, 86vh); }
.dialog--sm, .dialog--form { width: auto; }

/* COMPACT BY REQUEST (owner, 2 Aug 2026: "overly big text — I need it to be
   compact"). The Column Manager is a settings form, not a reading surface:
   twenty controls that a geologist scans and adjusts, so the useful measure is
   how many fit on screen at once, not how comfortable one line is. Type drops
   one step, the row rhythm tightens, and the 20px gap between control groups
   becomes 12 — which is what was actually making it feel oversized. */
.cm { display: grid; grid-template-columns: 250px 1fr; height: 100%; font-size: 13px; }
.cm__list { border-right: var(--hairline) solid var(--border); overflow-y: auto; padding: var(--s-2); }
.cm__detailwrap { overflow-y: auto; display: flex; flex-direction: column; }
.cm__detail { padding: var(--s-2) 16px var(--s-4); }
.cm__panetitle {
  font: var(--t-caption); font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--c-ink-2);
  padding: 8px var(--s-2) var(--s-2);
}
.cm__form { display: flex; flex-direction: column; gap: 12px; }
.cm label, .cm .field__label { font-size: 12px; }
.cm input[type=text], .cm input[type=number], .cm select { padding: 5px 7px; font-size: 13px; }
.cm .listrow { padding: 5px 8px; min-height: 30px; }
.cm .checkrow { padding: 3px 0; }
.cm .checkrow__hint { font-size: 11px; }
.cm .section__title { font-size: 11px; margin-bottom: 4px; }
.cm__back { display: none; }

/* ============================================================================
   PRINT / EXPORT DIALOG
   ========================================================================== */
.printdlg { display: grid; grid-template-columns: 340px 1fr; height: 100%; }
.printdlg__opts {
  padding: var(--s-5); overflow-y: auto;
  border-right: var(--hairline) solid var(--border);
  display: flex; flex-direction: column; gap: 20px;
}
.printdlg__preview {
  padding: var(--s-5); display: flex; flex-direction: column;
  align-items: center; justify-content: center; background: var(--ground);
}
.printdlg__page {
  width: min(320px, 60%); aspect-ratio: 210 / 297;
  background: #fff; box-shadow: var(--e2); border-radius: var(--radius-0);
  display: flex; flex-direction: column; padding: 14px;
}
.printdlg__hdr {
  font: 600 9px/1.3 var(--font-ui); color: var(--heading);
  border-bottom: 1px solid var(--heading); padding-bottom: 5px;
}
.printdlg__body {
  flex: 1; display: flex; align-items: center; justify-content: center;
  font: 11px var(--font-ui); color: var(--muted); margin: 6px 0;
  background:
    repeating-linear-gradient(0deg, transparent 0 13px, var(--border) 13px 14px),
    repeating-linear-gradient(90deg, transparent 0 44px, #DFE5EA 44px 45px);
}
.printdlg__ftr {
  display: flex; align-items: center; gap: 6px; font: 9px var(--font-ui); color: var(--body);
  border-top: 1px solid var(--heading); padding-top: 5px;
}
.printdlg__bar { display: inline-block; width: 40px; height: 6px; border: 1px solid var(--heading); border-top: none; }

/* ============================================================================
   DESCRIPTION PRESETS  —  the composer panel
   shared/ui/describe.js · docs/planning/25-description-presets.md §2

   Owner, 5 Aug 2026: *"It have empty textbox. We have five lithology group
   button. When one group category clicked, texture subgroup and structure
   subgroup populated."*

   Everything here is sized for a gloved thumb on a tablet held in one hand:
   the acceptance criteria ask for 44 dp touch targets and a flow that works
   one-handed with a stylus in the other (§6.8). That is why the terms are
   wrapping chips rather than a list of checkbox rows — a 320 px panel fits
   three chips a line and about eleven rows on screen, where checkbox rows fit
   seven and need a scroll for every sub-category.
   ========================================================================== */
.describe__text {
  width: 100%; min-height: 92px; resize: vertical;
  font-size: 13.5px; line-height: 1.5; text-align: left;
}
.describe__tools { display: flex; gap: var(--s-2); margin-top: var(--s-2); }

/* Five buttons, wrapping to two rows in the panel and staying one row wide in
   a portrait sheet. Not `ui.segmented`: at five items with names as long as
   "Metamorphic" a segmented control either scrolls sideways or truncates, and a
   lithology group truncated to "Metamor…" is a button nobody will trust. */
.describe__groups { display: flex; flex-wrap: wrap; gap: 6px; }
.describe__group {
  flex: 1 1 calc(50% - 6px); min-height: 44px; padding: 0 10px;
  border: var(--hairline) solid var(--border); border-radius: var(--radius-1);
  background: var(--card); color: var(--body); font: var(--t-label);
  cursor: pointer; white-space: nowrap;
}
.describe__group:hover { border-color: var(--primary); }
.describe__group.is-on {
  background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600;
}

.describe__recent { display: flex; flex-wrap: wrap; gap: 6px; }

/* ---- the accordions ------------------------------------------------------
   A closed row still says what is recorded in it, which is what makes eleven
   closed sub-categories readable rather than eleven things to open. */
.describe__acc { display: flex; flex-direction: column; }
.describe__subhead {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-height: 40px; padding: 4px 2px; border: 0; margin: 0;
  background: none; text-align: left; cursor: pointer;
  border-bottom: var(--hairline) solid var(--border-2);
}
.describe__subname { font: var(--t-label); color: var(--heading); white-space: nowrap; }
.describe__subsum {
  flex: 1; min-width: 0; font: var(--t-caption); color: var(--primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right;
}
.describe__subhead.is-open .describe__subsum { color: var(--muted); }

.describe__items {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px 2px 12px;
}
/* 44 px minimum on the short axis (§6.8). The chip grows with its label rather
   than being fixed-width: "very poorly sorted" and "clay" in equal boxes wastes
   two thirds of a narrow panel. */
.describe__item, .describe__chip {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 34px; padding: 0 10px;
  border: var(--hairline) solid var(--border); border-radius: 999px;
  background: var(--card); color: var(--body); font-size: 12.5px;
  cursor: pointer; white-space: nowrap;
}
.describe__item:hover, .describe__chip:hover { border-color: var(--primary); }
.describe__item.is-on, .describe__chip.is-on {
  background: var(--primary-lite, #ECF2FF); border-color: var(--primary);
  color: var(--primary); font-weight: 600;
}
/* A single-select chip is a radio wearing a chip's clothes, and the square
   corner is the one visual cue that says so — tapping it replaces rather than
   adds, which is a different promise from the pill beside it. */
.describe__item.is-single { border-radius: var(--radius-1); }
.describe__mod {
  font-size: 11px; padding: 1px 6px; border-radius: 999px;
  background: var(--warn); color: #3a2a00; font-weight: 600;
}

/* Expand all / Collapse all, at the head of each description accordion. */
.describe__all { margin: 0 0 4px auto; display: flex; }
