/*
 * The frame itself: the two-column dashboard, its widgets, and the two
 * fullscreen overlays. Nothing here scrolls and nothing here reloads.
 */

/* Idle bar ------------------------------------------------------------- */

/* Fills over the idle timeout, so the slideshow never arrives unannounced.
   The transform and its transition are driven from the frame controller. */
.idle-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 90;
  height: 3px;
  background-color: rgba(var(--primary-rgb), 0.5);
  transform-origin: left center;
}

/* Garland ------------------------------------------------------------- */

.garland {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  pointer-events: none;
}

.garland--dashboard {
  z-index: 80;
}

.garland--photos {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.garland__svg {
  display: block;
  width: 100%;
}

.garland__string {
  stroke: rgba(var(--content-rgb), 0.35);
}

.garland__knot,
.garland__thread {
  fill: rgba(var(--content-rgb), 0.5);
  stroke: rgba(var(--content-rgb), 0.4);
}

.garland--photos .garland__string {
  stroke: rgba(255, 255, 255, 0.35);
}

.garland--photos .garland__knot,
.garland--photos .garland__thread {
  fill: rgba(255, 255, 255, 0.5);
  stroke: rgba(255, 255, 255, 0.4);
}

/* Dashboard ------------------------------------------------------------ */

.dashboard {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  height: 100vh;
  padding: 1.5rem;
}

.dashboard__col {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-height: 0;
}

/* Clock ---------------------------------------------------------------- */

.clock {
  padding: 0 0.5rem;
  line-height: 1;
}

.clock__time {
  font-size: 4.5rem;
  font-weight: 300;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.clock__date {
  margin-top: 0.5rem;
  font-size: 1.875rem;
  color: rgba(var(--content-rgb), 0.7);
}

/* Weather -------------------------------------------------------------- */

.weather__now {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.weather__emoji {
  font-size: 4.5rem;
  line-height: 1;
}

.weather__temp {
  font-size: 3.75rem;
  font-weight: 300;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.weather__label {
  margin-top: 0.5rem;
  font-size: 1.5rem;
  color: rgba(var(--content-rgb), 0.7);
}

.weather__meta {
  text-align: right;
  font-size: 1.25rem;
  color: rgba(var(--content-rgb), 0.6);
  font-variant-numeric: tabular-nums;
}

.weather__forecast {
  display: grid;
  gap: 0.5rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(var(--content-rgb), 0.1);
}

.weather__forecast--hourly {
  grid-template-columns: repeat(6, 1fr);
}

.forecast {
  text-align: center;
}

.forecast__when {
  font-size: 1.125rem;
  color: rgba(var(--content-rgb), 0.6);
  font-variant-numeric: tabular-nums;
}

.forecast__icon {
  font-size: 1.875rem;
  line-height: 1.25;
}

.forecast__high {
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
}

/* Named only for an hour that will actually be wet, but the line is reserved
   whatever the forecast, so the strip keeps one height and the card below it
   never moves when a shower appears. 1rem of text on a 1.4 line box. */
.forecast__rain {
  min-height: 1.4rem;
  font-size: 1rem;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}

/* Sits in the meta column rather than on a row of its own, which the card has
   no height to spare for. */
.weather__stamp {
  margin-top: 0.35rem;
  font-size: 1rem;
  color: rgba(var(--content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.weather__empty {
  font-size: 1.875rem;
  color: rgba(var(--content-rgb), 0.4);
}

/* Calendar ------------------------------------------------------------- */

/* Today as a vertical hour grid, the way `frameo` draws it. The window is
   adaptive and comes from the server as a start minute and a span, so the
   card reads at the ~174px it has when the solar card is on. */

.timeline {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

/* Inset top and bottom, because the first and last hour labels are centred on
   their own lines and would otherwise hang over the card's edges. */
.timeline__grid {
  position: absolute;
  top: 0.55rem;
  right: 0;
  bottom: 0.55rem;
  left: 0;
  --gutter: 2.9rem;
}

.timeline__line,
.timeline__now {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  transform: translateY(-50%);
}

/* Hidden rather than dropped, so the rule keeps the width it had. */
.timeline__line--quiet .timeline__hour {
  visibility: hidden;
}

.timeline__hour {
  flex: none;
  width: 2.4rem;
  padding-right: 0.5rem;
  text-align: right;
  font-size: 0.8rem;
  line-height: 1;
  color: rgba(var(--content-rgb), 0.45);
  font-variant-numeric: tabular-nums;
}

.timeline__rule {
  flex: 1 1 auto;
  height: 0;
  border-top: 1px solid rgba(var(--content-rgb), 0.12);
}

/* Kept above the events, because an event that runs over now would otherwise
   swallow the one line that says where the day has got to. It carries no time
   of its own: the frame's clock is right above the card in 4.5rem type, and a
   second one here would land on top of an hour label. */
.timeline__now {
  z-index: 2;
  padding-left: var(--gutter);
}

.timeline__now .timeline__rule {
  border-top-color: var(--error);
}

.timeline__dot {
  flex: none;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background-color: var(--error);
}

/* A short event still has to show its title, so the bar has a floor in pixels
   and overshoots its end rather than rendering as an unreadable sliver. */
.timeline__event {
  position: absolute;
  z-index: 1;
  overflow: hidden;
  min-height: 1.35rem;
  padding: 0.1rem 0.35rem;
  border-left: 3px solid rgb(var(--feed));
  border-radius: 0 0.25rem 0.25rem 0;
  background-color: rgba(var(--feed), 0.18);
}

.timeline__title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.2;
  color: rgb(var(--feed));
}

/* All-day events carry no hour, so they sit above the grid as chips instead of
   as a bar that would have to span the whole of it. */
.timeline__allday {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.timeline__pill {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0.15rem 0.6rem;
  border: 1px solid rgba(var(--feed), 0.45);
  border-radius: 999px;
  font-size: 0.95rem;
  color: rgb(var(--feed));
  background-color: rgba(var(--feed), 0.14);
}

.timeline__empty {
  font-size: 1.875rem;
  color: rgba(var(--content-rgb), 0.4);
}

/* Fullscreen overlays --------------------------------------------------- */

.overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #000;
}

.overlay--photos {
  z-index: 100;
}

.overlay--night {
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Measurement panel ----------------------------------------------------- */

/* Above both overlays, so the numbers stay readable even after the frame has
   gone idle behind them. Read from a metre away, hence the size. */
.measure {
  position: fixed;
  top: 1.5rem;
  left: 1.5rem;
  z-index: 120;
  padding: 1.25rem 1.5rem;
  border-radius: var(--radius-box);
  background-color: rgba(0, 0, 0, 0.85);
}

.measure__output {
  margin: 0;
  font-family: monospace;
  font-size: 1.25rem;
  line-height: 1.45;
  color: #fff;
  white-space: pre;
}

/* Slideshow ------------------------------------------------------------ */

.slideshow {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #000;
}

.slideshow__slot {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  transition: opacity 1000ms linear;
}

.slideshow__backdrop,
.slideshow__photo {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* A blurred, dimmed copy fills the letterbox behind a photo that does not
   match the screen's shape. */
.slideshow__backdrop {
  object-fit: cover;
  filter: blur(20px) brightness(0.35);
  transform: scale(1.1);
}

.slideshow__photo {
  object-fit: contain;
}

/* Clock over the slideshow. text-shadow rather than a drop-shadow filter,
   which the frame's WebView renders far more cheaply. */
.slideshow-clock {
  position: absolute;
  bottom: 2.5rem;
  left: 2.5rem;
  line-height: 1;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.9);
}

.slideshow-clock__time {
  font-size: 6rem;
  font-weight: 300;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.slideshow-clock__date {
  margin-top: 0.25rem;
  font-size: 1.5rem;
  color: var(--warning);
}

/* Today's events over the slideshow ------------------------------------- */

/* Each plate is only as wide as its own line, because a fixed width painted a
   26rem box over the photo for the sake of "Frokost". The cap is what a long
   title is allowed to take before it is cut. */
.day-agenda {
  position: absolute;
  top: 2.5rem;
  left: 2.5rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 30%;
}

.day-agenda__item {
  display: flex;
  align-items: baseline;
  max-width: 100%;
  gap: 0.6rem;
  margin-bottom: 0.4rem;
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-field);
  background-color: rgba(0, 0, 0, 0.62);
}

.day-agenda__when {
  flex: none;
  white-space: nowrap;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--warning);
  font-variant-numeric: tabular-nums;
}

.day-agenda__title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 1.05rem;
  color: #fff;
}

.day-agenda__more {
  padding: 0 0.8rem;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.75);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.9);
}

/* Night clock ----------------------------------------------------------- */

.night-clock {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}

.night-clock__time {
  font-size: 12rem;
  font-weight: 300;
  letter-spacing: -0.02em;
  color: rgba(var(--neutral-content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.night-clock__date {
  font-size: 2.25rem;
  color: rgba(var(--neutral-content-rgb), 0.3);
}

/* Electricity ----------------------------------------------------------- */

.power__now {
  text-align: right;
  font-size: 1.25rem;
  color: rgba(var(--content-rgb), 0.6);
  font-variant-numeric: tabular-nums;
}

.power__now-price {
  font-size: 2rem;
  color: var(--content);
}

/* The bars are the widget. Each hour gets a slot of equal width and the bar
   grows from the bottom of it, so an hour that is nearly free still leaves a
   visible mark. The slots always share the full width, so a short window before
   Nord Pool publishes draws fewer, wider bars rather than leaving a gap. */
.power__chart {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 4.5rem;
}

.power__slot {
  display: flex;
  align-items: flex-end;
  flex: 1 1 0;
  height: 100%;
}

/* One clay colour in three weights, so height and colour say the same thing.
   A cheap hour barely marks the paper; a dear hour carries the full colour. */
.power__bar {
  width: 100%;
  border-radius: 3px 3px 0 0;
  background-color: var(--price-mid);
}

.power__bar--cheap {
  background-color: var(--price-low);
}

.power__bar--dear {
  background-color: var(--price-high);
}

/* The axis doubles as the ground the bars stand on, and the green segment marks
   exactly the hours the line underneath names. */
.power__axis {
  display: flex;
  gap: 3px;
}

.power__tick {
  flex: 1 1 0;
  padding-top: 0.3rem;
  border-top: 3px solid rgba(var(--content-rgb), 0.1);
  text-align: center;
  font-size: 0.875rem;
  color: rgba(var(--content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.power__tick--run {
  border-top-color: var(--price-run);
}

.power__run {
  font-size: 1.125rem;
  color: var(--price-run);
  font-variant-numeric: tabular-nums;
}

.power__stamp {
  font-size: 1rem;
  color: rgba(var(--content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.power__empty {
  font-size: 1.875rem;
  color: rgba(var(--content-rgb), 0.4);
}

/* Solar ---------------------------------------------------------------- */

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

.solar__charge {
  font-size: 1.875rem;
  line-height: 1;
}

.solar__stored {
  margin-left: 0.5rem;
  font-size: 1.125rem;
  color: rgba(var(--content-rgb), 0.6);
}

.solar__flow {
  font-size: 1.25rem;
  color: rgba(var(--content-rgb), 0.6);
  font-variant-numeric: tabular-nums;
}

.solar__flow--charging {
  color: var(--solar-charge);
}

.solar__flow--discharging {
  color: var(--solar-consumption);
}

.solar__gauge {
  overflow: hidden;
  height: 0.5rem;
  border-radius: 0.3rem;
  background-color: rgba(var(--content-rgb), 0.1);
}

.solar__gauge-fill {
  height: 100%;
  border-radius: 0.3rem;
  background-color: var(--solar-charge);
}

.solar__chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 2.25rem;
}

.solar__slot {
  display: flex;
  align-items: flex-end;
  gap: 1px;
  flex: 1 1 0;
  height: 100%;
}

.solar__bar {
  flex: 1 1 0;
  min-height: 1px;
  border-radius: 2px 2px 0 0;
}

.solar__bar--production {
  background-color: var(--solar-production);
}

.solar__bar--consumption {
  background-color: var(--solar-consumption);
}

.solar__bar--future {
  opacity: 0.35;
}

.solar__axis {
  display: flex;
  gap: 2px;
}

.solar__tick {
  flex: 1 1 0;
  padding-top: 0.3rem;
  border-top: 3px solid rgba(var(--content-rgb), 0.1);
  text-align: center;
  font-size: 0.875rem;
  color: rgba(var(--content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.solar__totals {
  font-size: 1.125rem;
  font-variant-numeric: tabular-nums;
}

.solar__total {
  color: rgba(var(--content-rgb), 0.6);
}

.solar__total + .solar__total {
  margin-left: 0.75rem;
}

.solar__total--production {
  color: var(--solar-production);
}

.solar__total--consumption {
  color: var(--solar-consumption);
}

.solar__stamp {
  font-size: 1rem;
  color: rgba(var(--content-rgb), 0.4);
  font-variant-numeric: tabular-nums;
}

.solar__empty {
  font-size: 1.875rem;
  color: rgba(var(--content-rgb), 0.4);
}

/* Collection schedule ---------------------------------------------------- */

/* Opposite the slideshow clock, which sits bottom-left. Only rendered on the
   two days before a collection, so the corner is empty most of the time. */
.waste {
  position: absolute;
  right: 2.5rem;
  bottom: 2.5rem;
  text-align: right;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.9);
}

.waste__when {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--warning);
}

.waste__bins {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* The tile is sized, not the figure: a label longer than its pictogram then
   widens the column instead of spilling over the next one. A busy Tuesday
   empties three containers at once, which is seven of these. */
.waste__bin {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
}

.waste__pictogram {
  display: block;
  width: 3.6rem;
  height: auto;
  border-radius: var(--radius-field);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}

.waste__label {
  margin-top: 0.15rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: #fff;
}

/* A fraction with no pictogram of its own still says what goes out. */
.waste__names {
  margin: 0;
  font-size: 1.1rem;
  color: #fff;
}
