/* Your place in Toastmasters — a printable structure chart for
   theclubupproject.com.

   Three palettes. The default is the live site's own: Montserrat, #1C208B
   blue, #FCC200 yellow. The other two are Toastmasters International's
   official brand colours, for anyone who wants the chart to sit inside
   club or district material rather than inside The Club Up Project.
   Montserrat is used throughout: the TI Brand Manual names Gotham as the
   primary typeface and Montserrat as its free stand-in, so the chart is
   already on-brand as far as a web page can be.

   Two audiences for this stylesheet: a reader on the screen inside a Google
   Sites iframe, and a sheet of A4 coming out of a printer. The iframe has a
   fixed height it cannot negotiate, so the stage scrolls internally. */

:root {
  --ink: #1c1c1c;
  --band-ink: var(--accent);
  --box: #f2f2f2;
  --muted: #5b5b66;
  --page: #ffffff;

  --gap: 8px;
  --radius: 8px;
}

/* The Club Up Project — the site this is embedded in. */
body[data-theme="tcup"] {
  --brand: #1c208b;
  --accent: #fcc200;
  --accent-ink: #1c1c1c;
  --box-line: #d8d8d8;
  --here-line: #c9cade;
}

/* Toastmasters International — Loyal Blue with Happy Yellow. */
body[data-theme="blue"] {
  --brand: #004165;
  --accent: #f2df74;
  --accent-ink: #1c1c1c;
  --box-line: #a9b2b1;
  --here-line: #a9b2b1;
}

/* Toastmasters International — True Maroon with Happy Yellow. */
body[data-theme="maroon"] {
  --brand: #772432;
  --accent: #f2df74;
  --accent-ink: #1c1c1c;
  --box-line: #a9b2b1;
  --here-line: #a9b2b1;
}

/* Yellow on the brand colour is the Toastmasters look; white is the quieter
   one, and the one that survives being projected. Only the bands take it —
   everywhere else the accent is a fill, not a font. */
[data-ink="white"] {
  --band-ink: #ffffff;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: Montserrat, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--page);
  -webkit-text-size-adjust: 100%;
}

/* ---------- controls ---------- */

.controls {
  padding: 14px 16px;
  background: var(--brand);
}

.controls__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 16px;
}

.controls__row--minor {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgb(255 255 255 / 0.2);
  align-items: center;
}

.controls__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 150px;
}

.controls__field--wide {
  flex: 1 1 260px;
}

.controls__field--exports {
  min-width: 0;
}

.exports {
  display: flex;
  /* Print, Save image and Copy image sit on one line wherever there is room for
     one, and on two where there is not. Unwrapped, they ran 45px off a 320px
     screen (#95). */
  flex-wrap: wrap;
  gap: 6px;
}

.controls .exports select {
  width: auto;
  font-size: 13px;
  padding: 9px 8px;
}

.controls .exports button {
  padding: 9px 14px;
  font-size: 13px;
}

.controls label,
.controls legend {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.controls select {
  font: inherit;
  font-size: 14px;
  padding: 8px 10px;
  border: 2px solid transparent;
  border-radius: 6px;
  background: #fff;
  color: var(--ink);
  width: 100%;
}

.controls select:disabled {
  color: var(--muted);
  background: #e7e7ef;
}

.controls :is(select, button, input):focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.controls button {
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  padding: 9px 18px;
  border: 0;
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
}

.controls button:disabled {
  opacity: 0.45;
  cursor: default;
}

.controls .button--quiet {
  background: transparent;
  color: #fff;
  border: 2px solid rgb(255 255 255 / 0.5);
  padding: 7px 14px;
}

/* ---------- colour swatches ---------- */

.swatches {
  display: flex;
  align-items: center;
  /* Wraps, because three named colours and a legend do not fit across a phone.
     The controls row around it has always wrapped; this one did not, so it ran
     115px off the side of a 320px screen and took the page with it (#95). */
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.swatches legend {
  float: left; /* a legend cannot be a flex item, so take it out of flow */
  margin-right: 12px;
  padding: 0;
  line-height: 24px;
}

.swatch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}

.swatch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.swatch__chip {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / 0.5);
  box-shadow: inset 0 0 0 2px #fff;
}

.swatch[data-swatch="tcup"] .swatch__chip {
  background: linear-gradient(135deg, #1c208b 50%, #fcc200 50%);
}

.swatch[data-swatch="blue"] .swatch__chip {
  background: linear-gradient(135deg, #004165 50%, #f2df74 50%);
}

.swatch[data-swatch="maroon"] .swatch__chip {
  background: linear-gradient(135deg, #772432 50%, #f2df74 50%);
}

.swatch[data-swatch="ink-accent"] .swatch__chip {
  background: var(--accent);
}

.swatch[data-swatch="ink-white"] .swatch__chip {
  background: #ffffff;
}

.swatch__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0.7;
}

.swatch input:checked ~ .swatch__chip {
  border-color: #fff;
  box-shadow:
    inset 0 0 0 2px #fff,
    0 0 0 2px var(--accent);
}

.swatch input:checked ~ .swatch__label {
  opacity: 1;
}

.swatch input:focus-visible ~ .swatch__chip {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- the region checkbox ---------- */

.check {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
}

.check input {
  width: 17px;
  height: 17px;
  accent-color: var(--accent);
  cursor: pointer;
}

.check span {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

/* Said, not shown: the chart says it on screen by redrawing, and a reader who
   cannot see it redrawn is told in a sentence instead. */
.sr-only {
  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;
}

.controls__status {
  /* Its own line under the export buttons: the messages run long, and a
     filename should not squeeze the controls beside it. */
  margin: 0;
  flex: 1 1 100%;
  min-width: 0;
  font-size: 11.5px;
  line-height: 1.4;
  color: #fff;
  opacity: 0.85;
}

/* ---------- names editor ---------- */

.editor {
  max-width: 1100px;
  margin: 16px auto 0;
  padding: 16px;
  border: 2px solid var(--box-line);
  border-radius: var(--radius);
  background: #fafafa;
}

.editor__title {
  margin: 0;
  font-size: 15px;
  font-weight: 800;
  color: var(--brand);
}

.editor__intro {
  margin: 6px 0 14px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  max-width: 60ch;
}

.editor__fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
}

.editor__group {
  margin: 0;
  padding: 8px 10px 10px;
  border: 1px solid var(--box-line);
  border-radius: 6px;
  background: #fff;
}

.editor__group legend {
  padding: 0 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brand);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 6px;
}

.field__label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.field__input {
  font: inherit;
  font-size: 13px;
  padding: 6px 8px;
  border: 1px solid var(--box-line);
  border-radius: 5px;
  background: #fff;
  color: var(--ink);
}

.field__input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

.editor__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  margin-top: 14px;
}

.editor__share {
  flex: 1 1 320px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.editor__share span {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.editor__share input {
  font: inherit;
  font-size: 12px;
  padding: 6px 8px;
  border: 1px solid var(--box-line);
  border-radius: 5px;
  background: #fff;
  color: var(--muted);
}

.editor__actions button {
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  padding: 8px 14px;
  border: 0;
  border-radius: 6px;
  background: var(--brand);
  color: #fff;
  cursor: pointer;
}

.editor__actions .button--quiet {
  background: transparent;
  color: var(--brand);
  border: 2px solid var(--box-line);
  padding: 6px 12px;
}

.editor__status {
  margin: 8px 0 0;
  min-height: 1.2em;
  font-size: 12px;
  color: var(--muted);
}

/* ---------- width controls (prototype) ---------- */

.controls__legend {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.widths {
  display: flex;
  gap: 6px;
}

.controls .width-preset {
  padding: 6px 12px;
  font-size: 12px;
  background: transparent;
  color: #fff;
  border: 2px solid rgb(255 255 255 / 0.4);
}

.controls .width-preset[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.controls__readout {
  font-size: 11.5px;
  color: #fff;
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
}

/* ---------- stage + sheet ---------- */

.stage {
  padding: 16px 24px;
}

/* The frame carries the width so the sheet can stay a plain stack of tiers,
   and so the grip has something to hang off that the export never sees. */
.frame {
  position: relative;
  width: min(var(--sheet-width, 1100px), 100%);
  margin: 0 auto;
}

.grip {
  position: absolute;
  top: 0;
  bottom: 0;
  right: -16px;
  width: 12px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: linear-gradient(var(--box-line), var(--box-line)) center / 4px 100% no-repeat;
  cursor: ew-resize;
  touch-action: none;
}

.grip::after {
  /* a thumb in the middle of the rail, so it reads as something to grab */
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 44px;
  border-radius: 6px;
  background: var(--brand);
  transform: translate(-50%, -50%);
}

.grip:hover::after {
  height: 64px;
}

.grip:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 3px;
}

.sheet {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.sheet__empty {
  margin: 0;
  padding: 48px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 15px;
}

/* ---------- tiers ---------- */

/* The full-width bar naming the level we are about to break open. */
.band {
  margin: 0;
  padding: 9px 14px;
  border-radius: var(--radius);
  background: var(--brand);
  color: var(--band-ink, var(--accent));
  font-size: clamp(15px, 2.1vw, 21px);
  font-weight: 800;
  text-align: center;
  letter-spacing: 0.01em;
}

/* The row of siblings sitting under a band. auto-fit keeps a four-division
   district and an eight-division one both looking deliberate. */
.row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--gap);
}

.row--areas {
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

/* Area boxes square off against the tallest in their row. The slack goes to
   the club list rather than the heading, so every "Area 17" still sits on the
   same line across the row and the clubs start directly under it. */
.row--areas .cell__body {
  flex: 0 0 auto;
}

.row--areas .clubs {
  flex: 1 1 auto;
}

.cell {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 2px solid var(--box-line);
  border-radius: var(--radius);
  background: var(--box);
  text-align: center;
}

/* The body is a <button> wherever the box leads somewhere, so the chart is
   navigable by keyboard and not only by mouse. Everything below strips the
   button back to looking exactly like the plain <div> version. */
/* The body fills the whole box. Boxes in a row are stretched to match the
   tallest, and a button that stopped at its own text left dead ground under
   the shorter ones — the reader aims at the box, not at the words. */
.cell__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  margin: 0;
  padding: 9px 10px;
  border: 0;
  border-radius: inherit;
  background: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
}

button.cell__body {
  cursor: pointer;
}

button.cell__body:hover {
  background: rgb(0 0 0 / 0.04);
}

button.cell__body:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: -3px;
}

.cell__name {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.25;
}

.cell__place,
.cell__meta {
  margin-top: 3px;
  font-size: 11px;
  line-height: 1.35;
  color: var(--muted);
}

.cell__meta {
  font-variant-numeric: tabular-nums;
}

/* All fourteen regions, once the reader opens them out. Narrower than the
   other tiers, because a region box holds two short lines at most. */
.row--regions {
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
}

/* The reader's own branch, at every level. */
.cell--here {
  background: #fff;
  border-color: var(--brand);
  border-width: 3px;
}

/* Somewhere the reader has wandered to rather than belongs to — another
   region, opened to see what is in it. Dashed, so the solid outline stays
   the mark of "this one is yours". */
.cell--open {
  background: #fff;
  border-color: var(--brand);
  border-width: 3px;
  border-style: dashed;
}

/* A short stem dropping out of the highlighted cell into the band below,
   so the eye can follow one path down the page. Only the cells that sit on
   the last line of a row get one — see placeStems(). A row of divisions that
   wraps would otherwise drop a stem into the gap above the next line, where
   it points at nothing. */
.cell--stem::after,
.cell--print-stem::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(-1 * var(--gap) - 1px);
  width: 3px;
  height: var(--gap);
  background: var(--brand);
  transform: translateX(-50%);
}

@media screen {
  .cell--print-stem:not(.cell--stem)::after {
    display: none;
  }
}

/* The areas are the bottom tier, so nothing hangs below them. Keyed off the
   row rather than :last-child, because the printed footnote follows. */
.row--areas .cell--stem::after,
.row--areas .cell--print-stem::after {
  display: none;
}

/* Clubs listed inside their Area box, rather than broken out into a tier of
   their own. */
.clubs {
  margin: 0 10px 9px;
  padding: 7px 0 0;
  border-top: 1px solid var(--box-line);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.clubs li {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--muted);
}

.club {
  display: block;
  width: 100%;
  margin: 0;
  padding: 1px 2px;
  border: 0;
  border-radius: 4px;
  background: none;
  font: inherit;
  color: inherit;
  text-align: center;
  cursor: pointer;
}

.club:hover {
  background: rgb(0 0 0 / 0.05);
  color: var(--ink);
}

.club:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -1px;
}

.clubs li.is-you .club {
  color: var(--accent-ink);
  font-weight: 700;
  background: var(--accent);
  padding: 2px 5px;
  margin: 1px 0;
}

.cell--here .clubs {
  border-top-color: var(--here-line);
}

/* ---------- colophon ---------- */

.colophon {
  max-width: 1100px;
  margin: 0 auto;
  padding: 4px 16px 24px;
}

.colophon p {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Shown in place of the lower tiers while the reader is looking at a region
   that is not their own. */
.sheet__hint {
  margin: 6px 0 0;
  padding: 14px;
  border: 2px dashed var(--box-line);
  border-radius: var(--radius);
  font-size: 12.5px;
  line-height: 1.5;
  text-align: center;
  color: var(--muted);
}

.sheet__footnote {
  margin: 2px 0 0;
  font-size: 10px;
  line-height: 1.45;
  color: var(--muted);
  text-align: right;
}

/* ---------- print ---------- */

/* The orientation is swapped by rewriting this rule at runtime — @page sits
   outside the document tree, so no class on <body> can reach it. This is the
   default, and what a printout gets if the script never ran. */
@page {
  size: A4 landscape;
  margin: 10mm;
}

@media print {
  [data-screen-only] {
    display: none !important;
  }

  .stage {
    padding: 0;
  }

  /* Paper has its own width; whatever was set for the screen does not apply. */
  .frame {
    width: 100%;
  }

  .sheet {
    gap: 4px;
  }

  /* The densest division in the Directory (D72 Division C: 8 areas, 44 clubs)
     filled an A4 landscape page to within a millimetre at screen sizes.
     Everything below is sized so that worst case lands around 150mm of the
     190mm available, leaving room for printer and browser variation. */
  .row--areas {
    grid-template-columns: repeat(auto-fit, minmax(152px, 1fr));
    gap: 4px;
  }

  /* Portrait has 190mm across instead of 277mm, so the boxes have to be
     narrower before the areas will sit in one band rather than two. */
  body[data-paper="portrait"] .row {
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  }

  body[data-paper="portrait"] .row--areas {
    grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
  }

  /* Keep ink off the page where the screen used fills for emphasis, but hold
     on to the two places colour is carrying meaning: the bands and the
     reader's own club. */
  .band {
    padding: 4px 10px;
    font-size: 11pt;
    background: var(--brand) !important;
    color: var(--band-ink, var(--accent)) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .cell {
    background: #fff !important;
    border-color: #999;
    break-inside: avoid;
  }

  .cell__body {
    padding: 3px 6px;
  }

  .cell--here,
  .cell--open {
    border-color: var(--brand) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .cell--stem:not(.cell--print-stem)::after {
    display: none;
  }

  .cell--print-stem::after {
    display: block;
    background: var(--brand) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .clubs li.is-you .club {
    background: var(--accent) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .cell__name {
    font-size: 8pt;
  }

  .cell__place,
  .cell__meta {
    font-size: 6pt;
  }

  .clubs li {
    font-size: 6pt;
    line-height: 1.25;
  }

  .clubs {
    margin: 0 6px 3px;
    padding-top: 4px;
    gap: 0;
  }
}
