/* Styling for the shell (see shell.js).
 *
 * Same two rules as every other piece: every colour, typeface and corner
 * comes from a token (D25), and every rule is one class on the element it
 * styles, so nothing reaches through a container into an element type.
 *
 * Text sizes and spacing are written here directly because there is no size
 * scale in tokens.css yet -- recorded in DECISIONS.md rather than claimed
 * otherwise.
 *
 * Anything that can be pressed gives at least the 40px a phone needs (D67).
 * The controls in this file use 44px, which is more than the floor, not a
 * second standard -- the shared "i" uses 40px exactly. Said this way round
 * because a stricter-sounding number in the file a reader hits first reads
 * as the rule, and then anything meeting the real rule looks like a mistake.
 *
 * The layout folds at 900px, which is the same width shell.js reads -- the
 * two are separate and are named in both places so they stay together.
 */

body {
  margin: 0;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
}

/* -------------------------------------------------------------- starting up
 *
 * What is on the page before the product has taken it over, and what stays
 * there if it never does. Styled from the tokens like everything else, so a
 * failure looks like part of the product rather than a broken page.
 */

.k-boot {
  padding: 24px 16px;
  font-family: var(--font);
  color: var(--text);
}

.k-boot__title {
  margin: 0 0 8px;
  font-family: var(--font);
  font-size: 20px;
  color: var(--brand);
}

.k-boot__text {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  color: var(--text-muted);
}

.k-boot__problem {
  margin: 12px 0 0;
  padding: 12px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text);
  background: var(--danger-bg);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius);
  white-space: pre-wrap;
  word-break: break-word;
}

.k-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* -------------------------------------------------------------- top bar */

/* **THE BAR STAYS PUT WHEN THE PAGE SCROLLS.** His words, looking at Items on
 * his own phone: it went up with everything else, so there was no boundary
 * anywhere and nothing said which business or which screen he was in once he
 * had scrolled a table.
 *
 * `sticky` rather than `fixed`: fixed takes the bar out of the layout and
 * everything below it slides up underneath by exactly its height, which is a
 * number that would then have to be kept in step with the bar's own padding in
 * two places. Sticky keeps its place in the flow and costs nothing.
 *
 * IT WORKS BECAUSE NOTHING ABOVE IT SCROLLS ON ITS OWN. `.k-shell` is a plain
 * flex column with no overflow of its own, so the page itself is what scrolls
 * and the bar has something to stick to. An `overflow` added to any ancestor
 * silently stops this working, with nothing on screen to say why.
 *
 * ABOVE THE CONTENT AND BELOW A DIALOG. The demonstration band above it is
 * meant to scroll away -- it is read once. A dialog is z-index 100 in
 * `modal.css` and has to cover everything, this included. */
.k-shell__bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  /* **ONE ROW, ALWAYS.** His words on a phone: it *"becomes two rows when it is
   * not able to accommodate everything... it should be single row only,
   * always."* Wrapping, it grew to two rows and then to three, and because the
   * bar is now sticky every one of those rows stayed on the screen for ever --
   * so the fix for the bar scrolling away made the wrapping worse.
   *
   * WHAT GIVES WAY INSTEAD: the business name shortens with an ellipsis, and
   * the words on the sign-out and alerts buttons drop below 600px leaving their
   * meaning to a title and a label a screen reader still reads. Nothing is
   * removed -- everything on this bar is still reachable at 320px. */
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
  padding: 4px 12px;
  /* **THE PADDING IS PART OF THE 56, not added to it.** Left as content-box
   * the bar came to 72px on his phone -- 56 of demanded content plus 16 of
   * padding -- while the tallest thing on it is 44. Sixteen pixels of nothing
   * across the top of every screen, and the bar is sticky, so they were
   * sixteen pixels he never got back. */
  box-sizing: border-box;
  /* **THINNER, because the bar is on every screen and never scrolls away.**
   * His review. It was 56 and the boxes round Alerts and Sign out held it
   * there; without them 44 is enough for anything on it, and the twelve pixels
   * go back to the work. */
  min-height: 44px;
  background: var(--brand);
  color: var(--on-brand);
}

.k-shell__brand {
  font-family: var(--font);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--on-brand);
}

/* The version stamp. Quiet enough to ignore while working, always there when
 * the question "am I looking at the new one?" comes up. The second face is
 * used because it is a stamp to be read character by character and compared,
 * not prose (D25). */

/* **NO BOX ROUND IT (his review).** *"You have this button type kind of border
 * around alerts and around sign out. This is what widening the top bar."* He is
 * right: an outline needs padding inside it to look deliberate, and that padding
 * was most of the bar's height. On a coloured bar the words are plainly
 * pressable without one. */
.k-shell__signout {
  /* A long email must not push the bar sideways on a phone. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.k-shell__signout-who {
  margin-left: 6px;
}

/* Below the width the sections sit down the left at, the name gives way and
 * the button is just the way out. Measured: it is what takes the bar from three
 * lines back to two on a 375px phone. */
@media (max-width: 899.98px) {
  .k-shell__signout-who {
    display: none;
  }
}

.k-shell__version {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--on-brand);
  opacity: 0.7;
  white-space: nowrap;
}

/* min-width: 0 is doing real work here, not tidying. Without it a name that
 * must not wrap refuses to shrink at all, so the ellipsis never appears and a
 * long business name pushes the Alerts button clean off a phone screen -- and
 * the page starts scrolling sideways, which is the one thing every screen in
 * this product is not allowed to do. */
/* **THE SWITCHER, WHERE THE BUSINESS'S NAME WOULD OTHERWISE BE (D146).**
 *
 * On the top bar rather than on a screen, because it is the one thing that has
 * to be true of every screen at once: whoever is looking has to be able to see
 * WHICH business's money they are looking at, from anywhere.
 *
 * ------------------------------------------ THREE THINGS HE FOUND, WITH A PHOTO
 *
 * **IT TOOK THE BUSINESS NAME'S PLACE ON SCREEN AND NOT ITS PLACE IN THE ROW.**
 * The name carries the `margin-left: auto` that pushes Alerts, Sign out and the
 * version stamp to the right-hand end. Hiding the name took that margin with it,
 * and the whole right-hand group collapsed leftwards into the brand. It is here
 * now, on whichever of the two is showing.
 *
 * **AND IT IS A BAR CONTROL, NOT A FORM CONTROL.** It was given `k-control` --
 * 37px, 16px, a visible border -- while everything else on this bar is `k-icon`
 * at 32px and 13px with no border at all. His words: *"we have removed border
 * from every other button on this top bar, so why does this need to be here?"*
 * It draws nothing until it is pointed at, like its neighbours.
 *
 * **AND IT MUST NOT TAKE THE BAR OVER.** A real business is called Rumee or BK
 * Store, not Sample Workshop -- but a name can be long, and 40vw of a phone is
 * most of the row. Narrow, and it ellipsises. */
.k-shell__switcher,
.k-shell__business {
  margin-left: auto;
}

.k-shell__switcher {
  max-width: 22ch;
  /* Room for the arrow the browser draws, and nothing more. */
  padding-right: 24px;
  color: var(--on-brand);
  text-overflow: ellipsis;
}

/* The list itself is drawn by the browser on the page's own background, not the
 * bar's, so it needs the page's own colours or it is white text on white. */
.k-shell__switcher option {
  color: var(--text);
  background: var(--surface);
}

.k-shell__business {
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--font);
  font-size: 13px;
  color: var(--on-brand);
  opacity: 0.9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Not connected is said quietly but plainly, never dressed up as a business. */
.k-shell__business--none {
  opacity: 0.65;
  font-style: italic;
}

.k-shell__alerts-count {
  min-width: 22px;
  padding: 2px 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  color: var(--on-danger);
  background: var(--danger);
  border-radius: var(--radius);
}

/* -------------------------------------------------------------- body */

.k-shell__body {
  flex: 1;
  display: flex;
  align-items: stretch;
  min-height: 0;
}

.k-shell__nav {
  flex: 0 0 220px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 8px;
  background: var(--surface);
  border-right: 1px solid var(--border);
}

.k-shell__nav-item {
  min-height: 44px;
  padding: 10px 12px;
  font-family: var(--font);
  font-size: 14px;
  text-align: left;
  color: var(--text);
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}

/* Only a section you are not already in lights up under the cursor.
 *
 * Written this way because a state like :hover counts for as much as a second
 * class and beats a plain modifier whatever the order. Left as a bare :hover,
 * pointing at the section you are currently in repainted its background to
 * near-white while its text stayed white -- the label disappeared, on the one
 * item you are most likely to be pointing at, right after clicking it.
 *
 * This is the third time the same trap has been logged on this project. It is
 * not "every rule is one class" that protects against it -- that claim does
 * not cover states at all. */
.k-shell__nav-item:hover:not(.k-shell__nav-item--on) {
  background: var(--surface-raised);
}

.k-shell__nav-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.k-shell__nav-item--on {
  color: var(--on-brand);
  background: var(--brand);
}

.k-shell__main {
  flex: 1;
  min-width: 0;
  padding: 16px;
}

/* -------------------------------------------------------------- banners */

.k-shell__banners {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.k-shell__banner {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 14px;
  padding: 12px 14px;
  background: var(--info-bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}

/* Something is actually broken, as opposed to merely worth knowing. */
.k-shell__banner--bad {
  background: var(--danger-bg);
  border-color: var(--danger-border);
}

.k-shell__banner-title {
  font-family: var(--font);
  font-size: 14px;
  color: var(--text);
}

.k-shell__banner-text {
  font-family: var(--font);
  font-size: 13px;
  color: var(--text-muted);
}

.k-shell__screen {
  min-width: 0;
}

/* -------------------------------------------------------------- screens
 *
 * The heading and the line under it that every screen starts with. Written
 * here rather than left to the browser's own heading size: a class applied
 * with no rule behind it is the reference's 690-orphan-class problem, and it
 * shipped on the very first screen of this product.
 */

/* **THE NAME AND WHAT THE SCREEN IS FOR SHARE ONE ROW (his review).**
 *
 * Stacked, they cost three rows before a seller reached a single record, on
 * every one of the twenty screens. Beside each other they cost one.
 *
 * **DONE HERE, ONCE, AND NOT IN TWENTY FILES.** He asked why the same work is
 * repeated tab by tab, and this is the answer in practice: no screen's own code
 * changes, so no screen can be missed and none can drift into doing it slightly
 * differently. Every screen already writes these two classes.
 *
 * AND THERE WAS A SECOND NAME FOR THE SECOND LINE -- `k-screen__explain`, on
 * nine screens, WITH NO RULE ANYWHERE BEHIND IT. Those nine were painting their
 * explanation with a class the stylesheet had never heard of, so it fell back
 * to the browser's own paragraph. That is the orphan-class fault this very
 * comment block warns about, sitting in the product. Folded into one name. */

/* **THE HEADING CARRIES THE `i` NOW, and the float is gone with the paragraph
 * it existed for.**
 *
 * His instruction, 2026-09-01: what a screen IS goes behind the mark
 * (`screenHeading` in `components/screen.js`). It was floated so the
 * explanation could sit beside it; there is no explanation beside it any more,
 * and a float with nothing to flow around only leaves a mess for whatever comes
 * next to clear.
 *
 * A row, so the mark sits ON the line with the words rather than under them --
 * a heading holding text and an element wraps the mark the moment the words are
 * long enough. */
/* **EVERY HEADING BUILT BY `screenHeading` carries `k-screen__head`**, whatever
 * else it is called -- a screen's name or a section's. One rule puts the mark on
 * the line with the words for all of them. */
.k-screen__head {
  display: flex;
  align-items: center;
  gap: 6px;
}

.k-screen__title {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
  font-family: var(--font);
  font-size: 20px;
  font-weight: 700;
  color: var(--brand);
}

.k-screen__intro {
  /* Its own box, so it sits BESIDE the name instead of wrapping under it, and
   * so nothing that follows has to know a float happened. */
  overflow: hidden;
  margin: 0 0 16px;
  max-width: 70ch;
  font-family: var(--font);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* **THE FLOAT-CLEARING RULE IS GONE with the float.** It existed so a heading
 * with no explanation beside it did not land on top of the next thing. Nothing
 * floats here now. */

/* -------------------------------------------------------------- phones
 *
 * The sections fold away behind the button in the top bar. Nothing is
 * hidden that cannot be reached, and nothing is dropped (D67).
 *
 * The fold is at 900px, written here as 899.98 and as 900 below, and read as
 * 900 by shell.js. The odd-looking .98 is the point: written as 899, a screen
 * measuring 899.5px -- perfectly normal with Windows display scaling or a
 * tablet split in two -- matched NEITHER rule. The permanent sections showed
 * AND the button showed, and pressing the button did nothing at all, because
 * the styling that opens the panel lives in this block. A dead button, from a
 * gap of half a pixel.
 */

@media (max-width: 899.98px) {
  .k-shell__nav {
    display: none;
  }

  .k-shell--nav-open .k-shell__nav {
    display: flex;
    flex: 1 1 auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }

  .k-shell--nav-open .k-shell__main {
    display: none;
  }

  .k-shell__body {
    flex-direction: column;
  }

  .k-shell__main {
    padding: 12px;
  }

  .k-shell__brand {
    font-size: 16px;
  }
}

/* On a wide screen the sections are always there, so the button is not. */
@media (min-width: 900px) {
  .k-shell__menu {
    display: none;
  }
}

/* -------------------------------------------- the demonstration mark */

/* ACROSS THE TOP OF EVERYTHING, above the top bar, on every screen. It is drawn
 * only in the demonstration mode, which cannot exist on a deployed Kartaan.
 *
 * IT IS DELIBERATELY LOUD. This is the one message where being ignored is the
 * failure -- somebody taking made-up figures for their own business. It uses the
 * danger colours rather than the quiet information ones for exactly that reason,
 * even though nothing is broken. */
.k-shell__made-up {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 10px 16px;
  background: var(--danger);
  color: var(--on-danger);
  border-bottom: 3px solid var(--accent);
}

.k-shell__made-up-title {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 700;
  color: var(--on-danger);
}

.k-shell__made-up-text {
  font-family: var(--font);
  font-size: 13px;
  color: var(--on-danger);
}

/* ON A PHONE THE SENTENCE GIVES WAY AND THE TITLE STAYS.
 *
 * Measured at 375px: with both, this band is 89px of an 812px screen -- on top
 * of a 116px top bar, that is a quarter of the phone gone before a single row of
 * anything. The shell's own note beside the version stamp records the same
 * measurement being taken for the sign-out name, and the same answer: the part
 * that carries the warning is the part that stays.
 *
 * IT IS STILL SPOKEN IN FULL. Hidden with `display: none` it would be gone for a
 * screen reader too, and somebody who cannot see the band is exactly who most
 * needs to be told none of this is real. `role="note"` on the band and the
 * sentence still in the page below it are what keep that true -- so this hides
 * it visually only, off the side of the screen rather than out of the document.
 */
@media (max-width: 899.98px) {
  .k-shell__made-up-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ------------------------------------------------ the bar on a small screen

/* **ONE ROW AT EVERY WIDTH.** Measured on his phone at 375px: the bar was
 * carrying the brand, the business name, the alerts button, a sign-out button
 * with a full email address on it and the version stamp, and it wrapped to two
 * rows -- both of which then stuck to the top of the screen and ate it.
 *
 * The order things give way in, widest first:
 *   - the version stamp goes. It is for answering "am I looking at the new
 *     one?", which is a thing somebody does at a desk;
 *   - the email comes off the sign-out button. The button still says what it
 *     does; who is signed in is on the This business screen;
 *   - the words come off the buttons below 600px, leaving the count and the
 *     icon. `aria-label` carries the meaning for anybody who cannot see them.
 */
@media (max-width: 600px) {
  .k-shell__bar {
    gap: 8px;
    padding: 8px;
  }

  /* The name of the business is the one thing here that is his own, so it is
   * the thing that shortens rather than the thing that goes. */
  .k-shell__business {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* **AND TIGHTER STILL ON A PHONE (his review).** *"If I open this in my
   * mobile screen it completely ruins the top bar. I want it small, matching
   * the formatting of other things on the top bar -- do not overtake
   * everything."* A business name can be long and the bar has four other things
   * on it. A third of the row is its share; past that the name ellipsises,
   * which is what the name it replaced already did. */
  .k-shell__switcher {
    max-width: 33vw;
  }

  .k-shell__brand {
    font-size: 16px;
  }

  /* **THE SECTIONS BUTTON BECOMES A HAMBURGER (his review).** The word takes
   * the width of two other controls on a phone, and the three bars are what
   * everybody already looks for. Not `display: none` on the word -- it is still
   * read out and still says what it does; only the printed word goes, and the
   * bars are drawn in its place. */
  .k-shell__menu-words {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .k-shell__menu::before {
    content: "\2261";
    font-size: 20px;
    line-height: 1;
  }

  .k-shell__menu {
    min-width: 44px;
    padding: 4px 8px;
  }

  /* NOT `display: none` -- it is still read out, still focusable, and still
   * says what it does. Only the printed word goes. */
  .k-shell__alerts-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .k-shell__signout {
    padding: 8px 10px;
    font-size: 12px;
  }
}

/* The version stamp is for a desk, not a godown. */
@media (max-width: 820px) {
  .k-shell__version {
    display: none;
  }
}

/* THE EMAIL COMES OFF THE BUTTON BEFORE THE BAR WRAPS. Who is signed in is a
 * thing to check now and then; it is on the This business screen, and it is the
 * longest thing on the bar by a wide margin -- a real address ran to 28
 * characters on a 375px screen. The button still says "Sign out". */
@media (max-width: 760px) {
  .k-shell__signout-who {
    display: none;
  }
}


/* -------------------------------------------- the head of a screen, on a phone

 * **HIS REVIEW: "before the table starts, there is a long list of things which
 * feels very unorganized in mobile screen... half of the screen is covered by
 * these things."** He is right, and the count is the argument: a title, three
 * lines of explanation, four buttons, a search box, a filter and a tickbox, all
 * before one item.
 *
 * **NOTHING IS REMOVED.** Every one of them is somebody's first errand on some
 * day, and a control that is only sometimes there is worse than a small one.
 * What changes is how much room they take.
 *
 * **AND IT IS DONE HERE, ONCE, FOR EVERY SCREEN.** Done per screen it would be
 * the button sizes all over again -- seven answers because seven days.
 */
@media (max-width: 600px) {
  /* **THE EXPLANATION FOLDS AWAY AFTER THE FIRST LINE.** It is written for
   * somebody meeting the screen for the first time, and read once. On the
   * hundredth visit it is three lines between them and their work. */
  /* **STILL ONE ROW ON A PHONE (his review).** I stacked them again here on the
   * assumption there was no width for both, and he looked at a real phone and
   * said no -- the folded explanation is one line, so the two together are one
   * line, which is the whole point of the change. An assumption about a small
   * screen is worth nothing until somebody holds one. */

  .k-screen__intro {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    margin: 0 0 10px;
    overflow: hidden;
  }

  .k-screen__title {
    /* The gap on the right is kept, or the explanation starts hard against the
     * last letter of the name -- this rule sets all four margins, so writing
     * the shorthand without it silently threw the wide-screen gap away. */
    margin: 0 10px 4px 0;
    font-size: 17px;
  }

  /* **THERE IS NO SMALLER BUTTON ON A PHONE ANY MORE.** There was one, at 38px,
   * for the same reason he has now applied everywhere -- and the moment every
   * button came down to 37px this rule was making them BIGGER on the small
   * screen than on the big one. **A size written in two places drifts, and the
   * one that drifts is always the one nobody is looking at.** One size, in
   * button.css, which is the file that owns it.
   *
   * It also had no business being in the shell's stylesheet: it styled
   * `.k-button`, which the shell does not own. */

  /* **AND THEY SIT TIGHTER TOGETHER.** Twelve pixels between every control is
   * generous on a desk and is most of a row on a phone. */
  .k-items__bar,
  .k-table__toolbar {
    gap: 8px;
    margin-top: 10px;
    padding: 8px;
  }
}

/* The two controls that still stood at 44 in the bar, holding it at 60. The
 * sign-out beside them was already 32; three things in a row at two heights is
 * what made the bar look padded rather than tall. */
@media (max-width: 600px) {
  .k-shell__menu,
  .k-shell__alerts {
    min-height: 32px;
    padding: 4px 8px;
  }
}
