/* Tuned for a 1280x800 CSS viewport, which is what the target tablet reports. Everything fits
   without scrolling in either orientation, text is readable at arm's length, and every target is
   at least 72 px so it works through a glove. Dark, high contrast, nothing that needs hovering.

   The palette follows the company logo: its navy as the ground, white for the mark and the
   wordmark, and one blue kept for the button that starts an estimate. */

:root {
  --bg-top: #0a1f31;            /* the logo's navy */
  --bg-bottom: #0b2740;
  --panel: #0e2639;
  --panel-high: #122e46;
  --line: #1d3d5a;
  --line-soft: #17344d;
  --text: #ffffff;
  --muted: #93a8bd;
  --faint: #2b4b69;
  --brand: #ffffff;              /* the logo is white on navy */
  --accent: #117ccf;
  --accent-high: #2a95e4;
  --good: #2fcf6e;
  --bad: #ef4444;
  --radius: 14px;
  --gap: 16px;
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* The hidden attribute only sets display:none at user-agent weight, so any class below that
   sets display would silently override it and the element would stay on screen. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 0 20px 0;
  /* Column with a growing middle, so the footer sits on the bottom edge even when the photo is
     short and there is room left over. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--bg-top) 0%, var(--bg-bottom) 100%);
  background-attachment: fixed;
  color: var(--text);
  font: 17px/1.45 "Segoe UI", Roboto, system-ui, sans-serif;
}

/* ------------------------------------------------------------------- top bar -- */

.bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;               /* on a narrow phone the product name drops to a second line */
  gap: 14px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line-soft);
}
.brand { display: flex; align-items: center; gap: 10px; }
.wordmark {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--brand);
}
.mark { width: 32px; height: 30px; fill: var(--brand); display: block; }

.bar h1 { margin: 0 0 0 4px; font-size: 19px; font-weight: 600; }
.product {
  margin: 0;
  padding-left: 14px;
  border-left: 1px solid var(--line);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.1;
}

/* ---------------------------------------------------------------- the photo -- */

main { flex: 1 1 auto; padding-top: var(--gap); }

.stage {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel-high) 0%, var(--panel) 100%);
  border: 1px dashed var(--line);
  overflow: hidden;
  display: grid;
  place-items: center;
}
.placeholder {
  display: grid;
  justify-items: center;
  gap: 14px;
  color: var(--faint);
}
.placeholder svg { width: 86px; height: 54px; }
.placeholder span {
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* The whole photo is always on screen. Both sides are free (width and height auto) and both are
   capped, so the picture is scaled down until all of it fits and the box ends up exactly the
   size of the picture: nothing is cropped, nothing spills, and no part of the frame is left
   over as a dark band. */
.stage img {
  display: none;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: var(--stage-max, 58vh);
}
/* Empty, the box keeps a 4:3 shape so the screen does not jump when a photo arrives. With a
   photo it takes the photo's own shape. */
.stage.has-image {
  aspect-ratio: auto;
  height: auto;
  background: none;
  border-color: transparent;
}
.stage.has-image img { display: block; }
.stage.has-image .placeholder { display: none; }
.stage.working img { filter: blur(10px) brightness(0.5); }

@supports not (aspect-ratio: 4 / 3) {
  .stage.empty { height: 0; padding-bottom: 75%; }
}

.spinner { position: absolute; inset: 0; display: grid; place-items: center; }
.spinner span {
  width: 54px; height: 54px;
  border: 5px solid rgba(255, 255, 255, 0.15);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner span { animation-duration: 2.4s; } }

/* ----------------------------------------------------------------- result -- */

.result {
  position: relative;
  margin-top: var(--gap);
  padding: 18px 22px;
  background: linear-gradient(180deg, var(--panel-high) 0%, var(--panel) 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
/* The green line is a stripe along the edge rather than a thick frame: same message, quieter. */
.result::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--good);
}
/* The mass is the whole point of the screen, so it gets the room. */
.mass { display: flex; align-items: baseline; gap: 10px; }
#mass-value { font-size: 80px; font-weight: 600; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.unit { font-size: 30px; color: var(--muted); }
.mass-label {
  color: var(--muted);
  margin-top: 6px;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.details { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.details div { display: flex; justify-content: space-between; gap: 12px; }
.details dt { color: var(--muted); margin: 0; font-size: 18px; }
.details dd { margin: 0; font-size: 18px; font-variant-numeric: tabular-nums; }

.problem {
  position: relative;
  margin-top: var(--gap);
  padding: 16px 22px;
  background: linear-gradient(180deg, #221a28 0%, var(--panel) 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: grid;
  gap: 6px;
  overflow: hidden;
}
.problem::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--bad);
}
.problem strong { font-size: 21px; }
.problem span { color: var(--muted); }

/* ---------------------------------------------------------------- buttons -- */

.actions { display: grid; gap: 12px; margin-top: var(--gap); }

.button {
  min-height: 76px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-high);
  color: var(--text);
  font: inherit;
  font-size: 20px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.08s ease, filter 0.15s ease;
}
.button:active { transform: scale(0.985); }
.button:focus-visible { outline: 2px solid var(--accent-high); outline-offset: 2px; }
.button:disabled { opacity: 0.45; }
.button.go {
  background: linear-gradient(180deg, var(--accent-high) 0%, var(--accent) 100%);
  border-color: var(--accent);
  color: #fff;
  box-shadow: 0 8px 24px rgba(17, 124, 207, 0.35);
}

/* ----------------------------------------------------------------- footer -- */

.foot {
  display: flex;
  justify-content: space-between;
  padding: 12px 2px 14px;
  margin-top: var(--gap);
  border-top: 1px solid var(--line-soft);
  color: var(--muted);
  font-size: 13px;
}

/* ------------------------------------------------------------- landscape -- */
/* Held sideways, which is how the tablet is used. The photo is the subject: it sits in the
   middle and takes every pixel the bar, the band and the footer leave it. Under it one row,
   aligned and sharing one height: the number on the left and the buttons on the right. */

@media (orientation: landscape) and (min-width: 820px) {
  html { height: 100%; }
  body {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;            /* nothing scrolls; if it does not fit, the photo gives way */
    padding: 0 20px;
  }

  .bar { flex: 0 0 auto; padding: 10px 2px; }
  .foot { flex: 0 0 auto; margin-top: 0; padding: 8px 2px 10px; }

  main { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding-top: 12px; }

  .stage { flex: 1 1 auto; min-height: 0; }
  /* Here the photo is stretched over the whole row and told to fit inside it, rather than being
     measured against it as in portrait. The row is a flex item whose height only exists once the
     rows above and below have taken theirs, and a percentage cannot be measured against a height
     that is not fixed yet -- written the portrait way, a tall photo would be cut off top and
     bottom. Stretched and contained, the picture is whole whatever shape it has.
     The shadow is a filter rather than a box-shadow because a filter follows the picture itself
     and a box-shadow would follow the whole row, drawing a frame around empty space. */
  .stage.has-image img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;          /* the portrait ceiling of 58vh must not survive into this layout */
    max-height: none;
    object-fit: contain;
    filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.55));
  }
  .stage.working img { filter: blur(10px) brightness(0.5); }

  /* One row, one fixed height. Fixed rather than minimum, because the photo above is told to
     take whatever is left: if this band could grow, the card would spill off the bottom edge
     instead of the photo giving way. */
  .side {
    flex: 0 0 auto;
    height: 118px;
    display: grid;
    grid-template-columns: minmax(300px, 1.5fr) minmax(280px, 1fr);
    align-items: stretch;
    gap: var(--gap);
    margin-top: var(--gap);
  }
  /* The secondary figure sits beside the big number rather than under it, which makes the whole
     band about fifty pixels shorter and hands them to the photo. */
  .result {
    grid-column: 1;
    margin-top: 0;
    padding: 10px 22px;
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "mass  . details"
      "label . details";
    align-items: center;
    column-gap: 24px;
  }
  .mass { grid-area: mass; align-self: end; }
  .mass-label { grid-area: label; align-self: start; }
  .details { grid-area: details; margin: 0; padding: 0; border-top: none; text-align: right; }
  .details div { display: block; }
  .details dt { font-size: 14px; }
  .details dd { font-size: 23px; margin-top: 2px; }
  .problem {
    grid-column: 1;
    margin-top: 0;
    padding: 10px 22px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* Buttons side by side, not stacked: two short blocks cost half the height of two tall ones,
     and the height saved is height the photo gets. */
  .actions {
    grid-column: 2;
    margin-top: 0;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    grid-auto-rows: 1fr;
    height: 100%;
    gap: 12px;
  }
  .button { min-height: 0; height: 100%; font-size: 19px; padding: 0 12px; }

  #mass-value { font-size: 58px; }
  .unit { font-size: 23px; }
  .mass-label { margin-top: 2px; font-size: 12px; }

  /* While there is no number the band holds nothing but buttons, so it shrinks to their height
     and the photo takes the difference. The buttons sit in the middle so the row is not lopsided. */
  .side:has(.result[hidden]):has(.problem[hidden]) {
    height: 84px;
    grid-template-columns: 1fr minmax(320px, 520px) 1fr;
  }
  .side:has(.result[hidden]):has(.problem[hidden]) .actions { grid-column: 2; }
}
