/* =========================================================
   LunchMate Board Display
   ========================================================= */


/* ---------------------------------------------------------
   Global
--------------------------------------------------------- */

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body {
  font-family: Arial, Helvetica, sans-serif;
  background: #ccc;
  margin: 0;
  padding: 0;
}

.restaurant-logo {
  height: 70px;
  width: auto;
  display: none;
  margin-bottom: 20px;
}

/*
    Extra padding above and below every row of a panel, shared out by
    board-density.js from the height the panel has left over. Set on
    the panel and inherited by its rows.

    Registered as a length so it can be animated: the rows of a panel
    on screen ease into new padding instead of jumping.
*/
@property --menu-item-extra-padding {
  syntax: '<length>';
  inherits: true;
  initial-value: 0px;
}

/* ---------------------------------------------------------
   Board viewport
--------------------------------------------------------- */

#boardViewport {
  width: 100vw;
  height: 100vh;
  position: relative;
}

/* ---------------------------------------------------------
   Logical board canvas
--------------------------------------------------------- */

/*
    IMPORTANT:

    The board itself always remains 1920 × 1080.

    We do NOT make this responsive.

    JavaScript scales the complete canvas when required.
*/

.board-canvas {
  width: 1920px;
  height: 1080px;
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: top left;
  background: #fff;
  overflow: hidden;
  /* One fixed card shadow for menu panels and the allergen key. */
  --board-panel-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);

  /*
      The four board colours, written here by JavaScript from the API.

      These are the defaults for a board that has not been painted
      yet: a panel with no background of its own sits straight on the
      board, in the board text colour.
  */
  --board-text-color: #000;
  --panel-background-color: transparent;
  --panel-text-color: var(--board-text-color);
}

#menuBoard {
  width: 100%;
  height: 100%;
  padding: 60px;
}

#promotionBoard {
  display: none;
  width: 100%;
  height: 100%;
}

/* ---------------------------------------------------------
   Board header
--------------------------------------------------------- */

.board-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 25px;
}

.board-header-left {
  display: flex;
  align-items: center;
  min-width: 0;
}

.restaurant-logo {
  height: 70px;
  width: auto;
  display: none;
  margin-bottom: 0;
  margin-right: 25px;
}

#boardName {
  margin: 0;
  white-space: nowrap;
}

.board-header-divider {
  width: 1px;
  height: 28px;
  margin: 0 20px;

  background: color-mix(
    in srgb,
    var(--board-text-color) 50%,
    transparent
  );
}

.board-header-subtitle {
  font-size: 28px;
  letter-spacing: 2px;
  white-space: nowrap;
}

.board-header-right {
  margin-left: auto;
  font-size: 28px;
  font-weight: 600;
  white-space: nowrap;
}

.menu-header-line {
  width: 100%;
  height: 2px;

  margin-bottom: 20px;

  background: color-mix(
    in srgb,
    var(--board-text-color) 30%,
    transparent
  );
}

/* ---------------------------------------------------------
   Columns container
--------------------------------------------------------- */

.columns-container {
  width: 100%;
  height: 780px;
  display: flex;
  gap: 20px;
  align-items: stretch;
}
.columns-container.no-footer-legend {
  height: 820px;
}

/*
    Density presets, on the 1920 x 1080 board. board-density.js tries
    them on each panel, roomiest first, and keeps the first one that
    panel fits in - panels next to each other can differ. Standard is
    the default until the panel has been measured.
*/
.board-column,
.board-column[data-density="standard"] {
  --menu-item-font-size: 26px;
  --menu-item-description-font-size: 18px;
}

.board-column[data-density="spacious"] {
  --menu-item-font-size: 30px;
  --menu-item-description-font-size: 20px;
}

.board-column[data-density="compact"] {
  --menu-item-font-size: 22px;
  --menu-item-description-font-size: 16px;
}

/* ---------------------------------------------------------
   Individual column
--------------------------------------------------------- */

.board-column {
  /*
        Width is set dynamically by JavaScript based
        on the width value received from the API.

        Example:
        40% + 60%
        50% + 50%
        60% + 40%
    */

  min-width: 0;
  height: 100%;
  padding: 25px;
  background: var(--panel-background-color);
  color: var(--panel-text-color);
  /* Panel border: the 25-35% band of the panel text. */
  border: 2px solid color-mix(in srgb, var(--panel-text-color) 30%, transparent);
  border-radius: 24px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Fixed panel depth. The same shadow is used on the allergen key.
     Managers cannot turn it off - it is the same on every board. */
  box-shadow: var(--board-panel-shadow);
}

/* ---------------------------------------------------------
   Column header
--------------------------------------------------------- */

.column-header {
  padding-bottom: 15px;
  margin-bottom: 20px;
  /* Category underline: the 80-100% band of the panel text. */
  border-bottom: 4px solid color-mix(in srgb, var(--panel-text-color) 80%, transparent);
}

.column-category-name {
  margin: 0 0 8px 0;
  font-size: 32px;
  line-height: 1.2;
}

/* ---------------------------------------------------------
   Column menu area
--------------------------------------------------------- */

/*
    This is deliberately empty for now.

    Later this will contain menu item templates.
*/

.column-items {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* ---------------------------------------------------------
   Temporary column footer
--------------------------------------------------------- */

.column-footer {
  padding-top: 15px;
  border-top: 1px solid color-mix(in srgb, var(--panel-text-color) 30%, transparent);
  font-size: 16px;
}

/* ---------------------------------------------------------
   Temporary display options
--------------------------------------------------------- */

.display-options {
  margin-top: 40px;
  padding-top: 25px;
  border-top: 2px solid color-mix(in srgb, var(--board-text-color) 30%, transparent);
}

.display-options h2 {
  margin: 0 0 20px 0;
  font-size: 28px;
}

.options-list {
  display: flex;
  gap: 40px;
  font-size: 20px;
}

.menu-item {
  font-size: var(--menu-item-font-size);
  width: 100%;
  padding: calc(10px + var(--menu-item-extra-padding)) 0;
  /* Item separator: the 15-20% band of the panel text. */
  border-bottom: 1px solid color-mix(in srgb, var(--panel-text-color) 20%, transparent);
  /* Items slide in from the right and out to the left, as in the
     mockup, and they are placed against the left edge of the column. */
  transform-origin: center left;
  will-change: transform, opacity;
}

/* A row that is growing or shrinking has to be clipped: its name,
   price and allergen icons are full size the whole time.

   This is only set while an item is arriving or leaving. It must not
   be left on, because the price pulse grows past the edge of its own
   row and would be cut off. */
.menu-item-entering,
.menu-item-removing {
  overflow: hidden;
}

/* A row that does not fit a panel even at the densest preset. Hidden
   rather than cut in half at the bottom of the panel, but still laid
   out - see board-density.js. */
.menu-item-clipped {
  visibility: hidden;
}

/* Says how many items a list that does not fit has left out. A short
   gap under the last item's separator, not a full item's padding, so
   the leftover space can still hold another row when it fits. Colour
   at 78% and 80% of the item name, from the ticket. Left/top/width
   are set in board-density.js from the last shown row. */
.menu-continuation {
  position: absolute;
  box-sizing: border-box;
  padding-top: 6px;
  font-size: calc(var(--menu-item-font-size) * 0.8);
  line-height: 1.2;
  color: color-mix(in srgb, var(--panel-text-color) 78%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

/* Special offer rows have no separators to sit under. */
.special-offers-column .menu-continuation {
  border-top: 1px solid color-mix(in srgb, var(--panel-text-color) 20%, transparent);
}

/* Chrome keeps the reading position steady when the content of a
   scrollable area changes, which fights the collapsing row. The
   continuation row is placed against this box. */
.column-items,
.category-items-column {
  position: relative;
  overflow-anchor: none;
}

/* Top aligned with a fixed line height, so the price and the allergen
   icons stay level with the first line of a name that wraps. */
.menu-item-row {
  display: flex;
  align-items: flex-start;
  width: 100%;
  line-height: 1.2;
}

.menu-item-name {
  /* A long name wraps rather than running into the price. The density
     is measured with the wrapped height, so the extra line counts. */
  min-width: 0;
  overflow-wrap: break-word;
  /* Medium/bold so the name reads as the title, not as the same
     weight as the description sitting under it. */
  font-weight: 600;
}

/*
    The description has to read as a second line, not as more of the
    title. Same left edge as the name, smaller and quieter, so from
    across a room the name is the thing that is read first.

    Size and opacity sit in the 70–80% band from the ticket. Opacity
    is used rather than a grey, so the description still follows the
    board text colour on a dark panel as well as a light one.
*/

.menu-item-description {
  margin-top: 5px;
  font-size: var(--menu-item-description-font-size);
  font-weight: 400;
  font-style: normal;
  line-height: 1.3;
  opacity: 0.75;
  text-align: left;
}

/* One line tall, so the icons are centred on the first line of the
   name and a row with icons is as tall as one without. */
.menu-item-allergens {
  display: flex;
  align-items: center;
  gap: 0.2em;
  height: 1.2em;
  margin-left: 0.5em;
  flex-shrink: 0;
}

/* A fixed box, so a row already has its final height before the icon
   has loaded - the density is measured straight after the board is
   drawn. */
.allergen-icon {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}

/* Sized from the item text, so the icons grow and shrink with the
   panel's preset instead of dominating Compact text. */
.menu-item-allergens .allergen-icon {
  width: 1.1em;
  height: 1.1em;
}

.menu-item-price {
  margin-left: auto;
  /* Keeps a gap to a name that has wrapped across the full width. */
  padding-left: 20px;
  margin-right: 0.2em;
  white-space: nowrap;
  flex-shrink: 0;
  overflow: visible;
  /* Price change pulse, as in the mockup. The mockup scales from the
     centre, but here the price sits against the edge of the column,
     which hides overflow - so it grows towards the left instead. */
  display: inline-flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 10px;
  transform-origin: right center;
  will-change: transform;
}

.menu-item-original-price {
  text-decoration: line-through;
  opacity: 0.6;
  font-weight: 400;
}

.menu-item-offer-price {
  display: inline-block;
  font-weight: inherit;
}

.menu-item-price.has-special-offer .menu-item-offer-price {
  font-weight: 700;
  opacity: 1;
}

#footerContainer {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 30px;
}

.footer-info {
  text-align: left;
  flex: 1;
}

/* The allergen key is a panel like the menu columns, so it is painted
   from the panel colours rather than from the board behind it. */
.footer-legends {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 15px;
  padding: 10px 15px;
  background: var(--panel-background-color);
  color: var(--panel-text-color);
  border: 1px solid color-mix(in srgb, var(--panel-text-color) 30%, transparent);
  border-radius: 12px;
  box-shadow: var(--board-panel-shadow);
}

.allergen-legend {
  display: flex;
  align-items: center;
  gap: 5px;
}

.allergen-legend img{
  width: 40px;
  height: 40px;
}

.allergen-key-title {
  font-weight: 600;
  white-space: nowrap;
}

#promotionFrame {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.one-category-two-columns {
  display: flex;
  gap: 50px;
}

.category-items-column {
  flex: 1;
  min-width: 0;
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

.category-items-column + .category-items-column {
  border-left: 1px solid color-mix(
    in srgb,
    var(--panel-text-color) 15%,
    transparent
  );
  padding-left: 50px;
}

/* ---------------------------------------------------------
   Board unavailable
--------------------------------------------------------- */

.board-unavailable {
  width: 100%;
  height: 100%;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 60px;
  font-size: 56px;
  font-weight: 700;
  color: #000;
}

/* ---------------------------------------------------------
   Promotion column
--------------------------------------------------------- */

.promotion-column {
  padding: 0;
  overflow: hidden;
  position: relative;
  border: none;
  border-radius: 0;
  background: transparent;
  /* A promotion is an iframe, not a menu panel - it must not pick
     up the card shadow from .board-column. */
  box-shadow: none;
}

/* A promotion page drawn as a panel is one more panel on the board. */
.promotion-column.promotion-column-panel {
  border-radius: 24px;
  box-shadow: var(--board-panel-shadow);
}

.promotion-column-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------------------------------------------------------
   Reduced motion
--------------------------------------------------------- */
/*
    Every live update animation is skipped in JavaScript, so nothing
    here has to be promoted to its own layer.
*/

@media (prefers-reduced-motion: reduce) {
  .menu-item,
  .menu-item-price {
    will-change: auto;
  }
}

/* ---------------------------------------------------------
   Special offers
--------------------------------------------------------- */
/*
    A group arrives and leaves whole, with the item row animation,
    which collapses padding but not margins. The space above a group's
    title is padding on the group for that reason - as a margin it is
    left behind while the group shrinks, and snaps shut at the end.
*/

.special-offers-column .column-category-name {
  text-transform: uppercase;
}

.special-offers-category {
  padding-top: 30px;
}

.special-offers-category-title {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 12px;
  font-size: calc(var(--menu-item-font-size) * 1.1);
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.2;
  text-transform: uppercase;
}

.special-offers-category-title::after {
  content: '';
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
}

.special-offers-category-items {
  width: 100%;
}
.special-offers-category-items .menu-item {
  border-bottom: none;
}