:root {
  --chrome: #f9f8f7;
  --chrome-line: #e1dfdd;
  --ink: #252423;
  --dim: #6e6d6b;
  --brand: #107c41;
  --ui: "Carlito", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

.sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.sr-block { position: absolute; top: 40vh; left: 0; right: 0; text-align: center; padding: 0 8vw; color: #605e5c; }

html, body {
  margin: 0; padding: 0; height: 100%;
  overflow: hidden;
  background: #f9f8f7;
  color: var(--ink);
  font: 12px/1.35 var(--ui);
  -webkit-font-smoothing: antialiased;
}

/*
 * width + overflow matter here: without them a status bar or tab strip that
 * cannot fit stretches the whole column past the viewport, and the canvas —
 * which measures itself off the stage — is silently drawn wider than the
 * screen and cropped on the right.
 */
.app {
  height: 100dvh; width: 100%; max-width: 100vw;
  display: flex; flex-direction: column;
  background: var(--chrome); user-select: none;
  overflow: hidden;
}
.app > * { min-width: 0; }
.titlebar, .ribtabs, .ribbon, .fbar, .stabs, .sbar { overflow: hidden; }
.stage { min-width: 0; }

/* ------------------------------------------------------------- title bar */

.titlebar { height: 30px; flex: 0 0 30px; display: flex; align-items: center; gap: 10px; padding: 0 8px; font-size: 11.5px; }
.tb-left, .tb-right { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.tb-right { justify-content: flex-end; }
.tb-mid { display: flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.tb-file { font-weight: 700; }
.tb-saved { color: var(--dim); }
.xl-mark { width: 17px; height: 17px; border-radius: 3px; background: var(--brand); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 11px; flex: 0 0 auto; }
.tb-auto { display: flex; align-items: center; gap: 5px; color: var(--dim); white-space: nowrap; }
.tb-auto i { width: 22px; height: 12px; border-radius: 7px; background: #c8c6c4; position: relative; display: inline-block; flex: 0 0 auto; }
.tb-auto i::after { content: ""; position: absolute; left: 2px; top: 2px; width: 8px; height: 8px; border-radius: 50%; background: #fff; }
.tb-auto b { color: var(--ink); font-weight: 600; }
.tb-icons { display: flex; align-items: center; gap: 8px; }
.tb-icons svg { display: block; opacity: .85; }
.tb-search { width: min(300px, 24vw); height: 20px; border-radius: 3px; background: #efeeed; color: var(--dim); display: flex; align-items: center; gap: 6px; padding: 0 8px; font-size: 11px; }
/* The two links out. Shaped like the title bar's own icon buttons and Excel's
   green Share button, and kept up here because this row survives every width. */
.tb-x { width: 22px; height: 20px; border-radius: 3px; display: grid; place-items: center; color: var(--ink); flex: 0 0 auto; }
.tb-x:hover { background: #e9e8e6; }
.tb-buy { height: 20px; padding: 0 10px; border-radius: 3px; display: flex; align-items: center; background: var(--brand); color: #fff; font-weight: 700; text-decoration: none; white-space: nowrap; flex: 0 0 auto; }
.tb-buy:hover { background: #0e6b38; }
.tb-x:focus-visible, .tb-buy:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.tb-win { display: flex; gap: 12px; color: var(--dim); font-size: 10px; }
.tb-win i { font-style: normal; }

/* ---------------------------------------------------------- ribbon tabs */

.ribtabs { height: 26px; flex: 0 0 26px; display: flex; align-items: stretch; gap: 2px; padding: 0 6px; font-size: 12px; }
.ribtab { display: flex; align-items: center; padding: 0 9px; color: #3b3a39; border-bottom: 2px solid transparent; white-space: nowrap; }
.ribtab.on { color: var(--brand); border-bottom-color: var(--brand); font-weight: 700; }
.ribtabs-sp { flex: 1; }
.ribchip { display: flex; align-items: center; padding: 0 8px; margin: 3px 0; border: 1px solid var(--chrome-line); border-radius: 3px; color: #3b3a39; font-size: 11.5px; }
.ribchip.share { background: var(--brand); color: #fff; border-color: var(--brand); }

/* --------------------------------------------------------------- ribbon */

.ribbon { height: 88px; flex: 0 0 88px; display: flex; background: #fff; border-bottom: 1px solid var(--chrome-line); padding: 3px 4px 0; overflow: hidden; }
.rgroup { display: flex; flex-direction: column; border-right: 1px solid #efeeed; padding: 0 8px; flex: 0 0 auto; }
.rgbody { flex: 1; display: flex; align-items: center; gap: 8px; }
.rglabel { text-align: center; color: #8a8886; font-size: 10px; padding-bottom: 2px; }
.big { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 4px 7px; font-size: 11px; color: #3b3a39; }
.big2 { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 3px 6px; font-size: 10.5px; line-height: 1.15; color: #3b3a39; text-align: center; }
.big svg, .big2 svg { display: block; }
.stack { display: flex; flex-direction: column; gap: 2px; }
.mini { display: flex; align-items: center; gap: 5px; font-size: 11px; color: #3b3a39; white-space: nowrap; }
.mini svg { display: block; flex: 0 0 12px; }
.mini .gl { flex: 0 0 12px; text-align: center; color: #605e5c; font-weight: 400; }
.col { display: flex; flex-direction: column; gap: 4px; }
.row { display: flex; align-items: center; gap: 2px; }
.field { height: 19px; min-width: 34px; padding: 0 5px; border: 1px solid #d2d0ce; border-radius: 2px; background: #fff; display: flex; align-items: center; font-size: 11.5px; color: #323130; }
.field.wide { min-width: 88px; }
.field.num { min-width: 30px; }
.btn { min-width: 20px; height: 19px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center; border-radius: 2px; color: #3b3a39; font-size: 11.5px; }
.btn.b { font-weight: 700; } .btn.i { font-style: italic; } .btn.u { text-decoration: underline; }
.btn.swatch { flex-direction: column; gap: 1px; padding: 2px 3px; font-size: 8px; }
.btn.swatch em { display: block; width: 12px; height: 3px; }
.sep { width: 1px; height: 15px; background: #e6e4e2; margin: 0 3px; }
.chip { height: 19px; padding: 0 6px; display: inline-flex; align-items: center; border-radius: 2px; font-size: 11px; color: #3b3a39; white-space: nowrap; }

/* ---------------------------------------------------------- formula bar */

.fbar { height: 24px; flex: 0 0 24px; display: flex; background: #fff; border-bottom: 1px solid var(--chrome-line); padding: 2px 6px; }
.namebox { width: 108px; border: 1px solid #d2d0ce; border-radius: 2px; display: flex; align-items: center; padding: 0 6px; font-size: 11.5px; color: #323130; font-variant-numeric: tabular-nums; }
.fb-btns { display: flex; align-items: center; gap: 9px; padding: 0 9px; color: #a19f9d; font-size: 10px; }
.fb-btns i { font-style: normal; }
.fb-btns .fx { font-style: italic; font-weight: 700; color: #605e5c; }
.fb-input { flex: 1; display: flex; align-items: center; border-left: 1px solid #e6e4e2; padding: 0 8px; font-size: 12px; color: #323130; white-space: nowrap; overflow: hidden; }

/* ---------------------------------------------------------------- stage */

.stage { flex: 1; position: relative; min-height: 0; background: #fff; }
/* Starts hidden and is faded up once the first frame is on it — see boot(). */
.sheetCanvas { display: block; width: 100%; height: 100%; cursor: cell; touch-action: none; opacity: 0; }

/* Landscape puts the caption beside the subject, not on top of it. */
.overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center;
  padding: 0 0 4vh 7vw;
  pointer-events: none; opacity: 0;
}
.ol-line {
  display: block;
  font-size: clamp(30px, 5.4vw, 84px);
  line-height: 1.11;
  letter-spacing: -.012em;
  color: #fff;
  opacity: 0;
  text-shadow: 0 2px 46px rgba(0,0,0,.62), 0 2px 10px rgba(0,0,0,.42), 0 1px 3px rgba(0,0,0,.38);
  /* Transform and opacity only: both are the compositor's, and a `filter` hint
     here promoted a full-viewport layer that had to be re-rasterised whether or
     not anything was blurring it. */
  will-change: transform, opacity;
}

/* Where the caption stands. Every sheet used to caption itself in the same
   bottom-left corner, which is the layout of a template rather than of nine
   different pictures — and it fought whichever subject happened to be there. */
.overlay.at-centre { align-items: center; text-align: center; padding: 0 6vw 2vh; }
.overlay.at-right { align-items: flex-end; text-align: right; padding: 0 7vw 4vh 0; }
.overlay.at-low { justify-content: flex-end; padding: 0 0 9vh 7vw; }
.overlay.at-high { justify-content: flex-start; padding: 9vh 7vw 0 0; align-items: flex-end; text-align: right; }

/* Portrait stacks them: caption up top, subject underneath. Placement is a
   landscape decision — a phone has one column and the subject is under it. */
@media (max-aspect-ratio: 1/1) {
  .overlay,
  .overlay.at-centre, .overlay.at-right, .overlay.at-low, .overlay.at-high {
    align-items: center; justify-content: flex-start;
    padding: 7vh 5vw 0; text-align: center;
  }
  .ol-line { font-size: clamp(30px, 9vw, 72px); }
}

.hint {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  color: rgba(255,255,255,.72); font-size: 11px; letter-spacing: .085em;
  pointer-events: none; opacity: 0;
  padding: 5px 12px; border-radius: 20px;
  background: rgba(6, 16, 10, .46);
  backdrop-filter: blur(3px);
}

/* ----------------------------------------------------------- sheet tabs */

.stabs { height: 25px; flex: 0 0 25px; display: flex; align-items: stretch; gap: 1px; border-top: 1px solid var(--chrome-line); padding: 0 6px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.stabs::-webkit-scrollbar { display: none; }
.snav { display: flex; align-items: center; gap: 6px; padding-right: 10px; color: #a19f9d; font-size: 9px; }
.stab { display: flex; align-items: center; padding: 0 11px; font-size: 11.5px; color: #605e5c; white-space: nowrap; border-top: 2px solid transparent; }
.stab.on { background: #fff; color: var(--brand); font-weight: 700; border-top-color: var(--brand); }
.stab.add { color: #a19f9d; padding: 0 9px; }

/* The three sheets that woke up. They are the only ones worth clicking, and
   they have to look it without stopping being Excel's own tab strip. */
.stab.live { cursor: pointer; color: #3a3937; letter-spacing: .04em; }
.stab.live::before {
  content: ""; width: 5px; height: 5px; margin-right: 6px; border-radius: 50%;
  background: var(--brand); opacity: .55;
}
.stab.live:hover { background: #eef6f1; color: var(--brand); }
.stab.live:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.stab.live.on::before { opacity: 1; }

/* ---------------------------------------------------------- status bar */

.sbar { height: 23px; flex: 0 0 23px; display: flex; align-items: center; gap: 14px; border-top: 1px solid var(--chrome-line); padding: 0 10px; font-size: 11px; color: #605e5c; }
.sb-ready { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sb-sp { flex: 1; }
.sb-sep { width: 1px; height: 12px; background: #d2d0ce; }
.sb-stat { font-variant-numeric: tabular-nums; white-space: nowrap; }
.sb-acc { color: #8a8886; }
/* Excel's own sheet counter, and the only thing on the page that says out loud
   how many worlds there are before a visitor has waited half a minute to be
   shown the second one. It is the last thing to be dropped on a narrow window. */
.sb-sheet { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sb-ca { font: inherit; background: none; border: 0; padding: 0; color: var(--brand); font-weight: 700; letter-spacing: .02em; cursor: default; }
.sb-ca.live { cursor: pointer; }
.sb-link { color: #605e5c; text-decoration: none; font-weight: 700; }
.sb-link:hover { color: var(--brand); }
.sb-zoom { font-variant-numeric: tabular-nums; width: 42px; text-align: right; }
.sb-slider { position: relative; width: 92px; height: 12px; }
.sb-slider::before { content: ""; position: absolute; left: 0; right: 0; top: 5px; height: 1px; background: #c8c6c4; }
.sb-slider i { position: absolute; top: 1px; width: 3px; height: 10px; background: #605e5c; border-radius: 1px; transform: translateX(-50%); }

/* --------------------------------------------------------------- narrow */

@media (max-width: 1180px) { .rgroup:nth-child(4) { display: none; } }
@media (max-width: 1020px) { .rgroup:nth-child(7), .rgroup:nth-child(6) { display: none; } .tb-search { display: none; } .sb-acc { display: none; } }
@media (max-width: 820px)  { .rgroup:nth-child(3) { display: none; } .sb-stat { display: none; } }
@media (max-width: 660px) {
  .ribbon, .ribtabs { display: none; }
  .tb-saved, .tb-auto, .tb-icons, .tb-win { display: none; }
  /* The X and Buy links keep their room; the opening file name is what gives. */
  .tb-left, .tb-right { flex: 0 0 auto; }
  .tb-mid { flex: 1; min-width: 0; overflow: hidden; justify-content: center; }
  .tb-file { overflow: hidden; text-overflow: ellipsis; }
  .sb-ready, .sb-slider { display: none; }
  .sbar { gap: 10px; padding: 0 8px; }
  .stabs { padding: 0 4px; }
  .stab { padding: 0 8px; }
  .snav { display: none; }
  .hint { font-size: 10px; bottom: 8px; }
}

/* ------------------------------------------------- the working spreadsheet */

/*
 * Everything below is chrome that had been drawn but not wired. The piece is a
 * picture of Excel; these are the parts of Excel a visitor's hands go to first,
 * and a name box you cannot type in is the one detail that gives the whole
 * illusion away the moment somebody tests it.
 *
 * The rule the rest of the file follows still holds: none of this may LOOK
 * different from what was there. A working control that announces itself is a
 * worse lie than a dead one.
 */

/* Native inputs inherit nothing; these two are already styled as Excel's. */
.namebox, .fb-input, .celledit {
  font: inherit; background: transparent; color: inherit;
  outline: none; -webkit-appearance: none; appearance: none;
}
.namebox { font-size: 11.5px; }
.namebox:focus, .fb-input:focus { background: #fff; }
.namebox:focus { border-color: var(--brand); }
.fb-input { border: 0; border-left: 1px solid #e6e4e2; }
/* Excel greys the cancel and enter ticks until there is something to cancel. */
.fb-btns button {
  font: inherit; font-size: 10px; line-height: 1; padding: 0; border: 0;
  background: none; color: #c8c6c4; cursor: default;
}
.fbar.editing .fb-btns button { color: #605e5c; cursor: pointer; }
.fbar.editing .fb-btns button:hover { color: var(--brand); }
.fbar.editing #fbCancel:hover { color: #c43e1c; }

/* The in-cell editor. Excel's sits ON the cell, overflowing to the right if it
   has to, with the caret where the eye already is — and it is never smaller
   than you can read, however far out the sheet is zoomed. */
.celledit {
  position: absolute; z-index: 3;
  min-width: 62px; height: 19px; padding: 0 3px;
  background: #fff; color: #10262e;
  border: 2px solid var(--brand);
  box-shadow: 0 1px 6px rgba(0,0,0,.28);
  font-size: 12px; line-height: 1;
}

.tb-btn {
  border: 0; background: none; padding: 0; color: #605e5c;
  display: inline-flex; cursor: pointer; border-radius: 2px;
}
.tb-btn:disabled { color: #c8c6c4; cursor: default; }
.tb-btn:not(:disabled):hover { background: #eceaea; }
.tb-btn svg { display: block; }

/* Bold and italic apply to the selected cell, so they light up like Excel's. */
button.btn { border: 0; background: none; font-family: inherit; cursor: pointer; }
button.btn:hover { background: #eceaea; }
button.btn.on { background: #cdeadb; color: #0b5c31; }

.sb-zoom { border: 0; background: none; font: inherit; color: inherit; cursor: pointer; padding: 0; }
.sb-zoom:hover { color: var(--brand); }
.sb-slider { cursor: pointer; touch-action: none; }
.sb-slider:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* The tab strip's own navigation, which Excel puts there and which was text. */
.snav button {
  border: 0; background: none; font: inherit; color: inherit;
  padding: 0 1px; cursor: pointer;
}
.snav button:disabled { opacity: .45; cursor: default; }
.snav button:not(:disabled):hover { color: var(--brand); }

/* A cell being edited is a moment, not a mode: no motion behind it. */
@media (prefers-reduced-motion: reduce) {
  .celledit { box-shadow: none; }
}

/* Eight of the nine worlds are darker than their subject, so the caption is
   white with the dark under it. DUSK is the one that is not, and white type on
   a pale sky is something you can find rather than something you can read —
   the same reason its word ends up black where every other sheet's is white. */
.overlay.ink-dark .ol-line {
  color: #14181f;
  text-shadow: 0 2px 40px rgba(255,255,255,.72), 0 2px 9px rgba(255,255,255,.6), 0 1px 2px rgba(255,255,255,.5);
}

/* Safari zooms the whole page when a focused input's type is under sixteen
   pixels, which on a phone would throw the sheet across the screen the moment
   somebody opened a cell. The editor's size is set inline off the zoom, so this
   has to outrank it. */
@media (pointer: coarse) {
  .celledit { font-size: 16px !important; height: 26px; min-width: 90px; }
}

/* Ribbon commands that do something. They must not look any different from the
   ones that do not — a working button that announces itself is a worse lie than
   a dead one — so this only adds the hover Excel already gives them. */
/* font-family, not the `font` shorthand, and the padding restated: a button's
   UA styles are a 13px system face and 1px/6px of padding, and `font: inherit`
   would take the 12px off .rgbody rather than the 11px .mini asks for. Either
   way Cut and Copy came out a pixel larger and six pixels wider than the Format
   Painter beside them, which is exactly the tell this is meant not to leave. */
button.mini, button.big {
  border: 0; background: none; color: inherit; cursor: pointer;
  font-family: inherit; font-size: 11px; font-weight: 400; line-height: inherit;
  padding: 0; text-align: left; border-radius: 2px;
}
button.big { padding: 4px 7px; text-align: center; }
button.mini:hover, button.big:hover { background: #eceaea; }
button.mini:disabled, button.big:disabled { color: #a19f9d; cursor: default; background: none; }

/* The Number group's format chip and the alignment buttons light up the way
   Excel's do when they describe the selected cell. Same shape as the dead
   controls beside them — see the note on button.mini above. */
button.field, button.chip {
  border: 1px solid #d2d0ce; background: #fff; font-family: inherit;
  font-size: 11.5px; color: #323130; cursor: pointer;
}
button.chip { border: 0; background: none; font-size: 11px; color: #3b3a39; border-radius: 2px; }
button.chip:hover { background: #eceaea; }
button.chip.on { background: #cdeadb; color: #0b5c31; }
button.field:hover { border-color: var(--brand); }

/* Find, which Excel opens as a dialog over the sheet. */
/* [hidden] and a class rule are the same specificity, so the later one wins —
   and a rule that sets display:flex is later than the browser's own
   [hidden]{display:none}. The Find box was permanently open. */
.finder[hidden] { display: none; }
.finder {
  position: absolute; z-index: 4; top: 12px; right: 12px;
  display: flex; align-items: center; gap: 7px;
  background: #fff; border: 1px solid #c8c6c4; border-radius: 3px;
  box-shadow: 0 4px 18px rgba(0,0,0,.28); padding: 7px 9px; font-size: 11.5px;
}
.finder input {
  width: 160px; height: 21px; padding: 0 6px; font: inherit;
  border: 1px solid #d2d0ce; border-radius: 2px; background: #fff; color: #323130;
}
.finder input:focus { outline: none; border-color: var(--brand); }
.finder button {
  height: 21px; padding: 0 9px; font: inherit; cursor: pointer;
  border: 1px solid #d2d0ce; border-radius: 2px; background: #f3f2f1; color: #323130;
}
.finder button:hover { border-color: var(--brand); color: var(--brand); }
.finder #findClose { padding: 0 6px; border: 0; background: none; color: #605e5c; }
.find-note { color: var(--dim); font-variant-numeric: tabular-nums; min-width: 54px; }
@media (max-width: 660px) {
  .finder { left: 12px; right: 12px; }
  .finder input { width: auto; flex: 1; min-width: 0; }
}

/* The ten tabs that are rendered rather than written out, and the panel the
   commands that would open a dialog write into instead. */
.ribbon.alt { gap: 0; }
.ribbon.alt .rgbody { gap: 10px; align-items: flex-start; padding-top: 6px; }
.ribbon.alt .big2 { gap: 4px; min-width: 74px; max-width: 104px; }
.ribbon.alt .big2 .gl { font-size: 17px; line-height: 1.1; color: #3b3a39; }
.ribbon.alt .mini { padding: 2px 3px; }
.ribbon.alt .mini .gl { width: 14px; text-align: center; }
.ribbon.alt .big2.on, .ribbon.alt .mini.on { background: #cdeadb; color: #0b5c31; }
.ribbon.alt .big2.on .gl, .ribbon.alt .mini.on .gl { color: #0b5c31; }
.ribtab { border: 0; background: none; font-family: inherit; cursor: pointer; }
.ribtab:hover { color: var(--brand); }

.sheetinfo {
  position: absolute; z-index: 4; left: 50%; bottom: 44px; transform: translateX(-50%);
  max-width: min(560px, 88vw);
  background: #fff; color: #323130; border: 1px solid #c8c6c4; border-radius: 4px;
  box-shadow: 0 6px 26px rgba(0,0,0,.32); padding: 11px 15px;
  font-size: 12px; line-height: 1.55;
}
.sheetinfo[hidden] { display: none; }
.sheetinfo b { color: #1a1a1a; }
.sheetinfo kbd {
  font: 11px var(--ui); background: #f3f2f1; border: 1px solid #d2d0ce;
  border-bottom-width: 2px; border-radius: 3px; padding: 0 4px;
}
.fbar[hidden] { display: none; }
/* Same trap as .finder: a class that sets display outranks [hidden]. */
.ribbon[hidden] { display: none; }
