/*
  Renta answering the thumb.

  A page built for a mouse feels dead on a phone for four reasons, and this
  file is those four reasons and nothing else:

    1. Hover does the work. On a touch screen :hover fires on tap and then
       STAYS, so a card lifts when you press it and stays lifted after you
       have gone - the one moment feedback was wanted, it is late, and then
       it never leaves.
    2. Nothing moves under the finger. A tap either navigates or it does
       not, with no instant of acknowledgement in between, so a slow page
       reads as a broken button and gets pressed again.
    3. Nothing marks the WAIT. Every page here is drawn on the server, so a
       tap is followed by a silence of unknown length. A line across the top
       edge turns that silence into "it is coming".
    4. The targets are mouse-sized. A 28px pill is a comfortable click and
       an uncomfortable tap; the thumb wants 44px and the row it sits in
       wants the whole width, not the six characters of the link.

  The press itself is deliberately NOT behind a touch query: a button that
  gives when it is pushed is right under a mouse too, and it is the only
  part of this that can be seen in a desktop preview pane. Everything that
  would be wrong on a desktop - undoing hover, growing every target to 44px
  - is behind (hover: none) further down.

  The pressed state is driven by .is-pressed from /js/touch.js rather than
  :active, because on iOS :active is withheld until the browser is sure the
  touch is not the start of a scroll, which is exactly the 150ms in which a
  button needed to have already answered.
*/

/* ---- the press, everywhere -------------------------------------------- */
/*
  Down is immediate, up eases back: the thing should give the instant it is
  touched, and the release is what can afford to be smooth. The scale is on
  whatever the finger is actually over, so a whole card gives, not just the
  word inside it.
*/
.is-pressed {
  transform: scale(.97);
  filter: brightness(.93);
  transition: transform 60ms ease-out, filter 60ms ease-out;
}

/* something the size of a card only needs to breathe, not shrink */
.card.is-pressed,
.tile.is-pressed,
.who-card.is-pressed,
.person-card.is-pressed,
.rail-card.is-pressed,
.tenant-pick.is-pressed .box,
[data-tap-href].is-pressed {
  transform: scale(.985);
}

/*
  A link is words. Words must not shrink under a finger - it looks like the
  type is broken - so a plain link answers by dimming for the instant it is
  held. It is the same acknowledgement, said the way text can say it.
*/
.is-pressed-soft {
  opacity: .55;
  transition: opacity 60ms ease-out;
}

/* and the release, for everything not currently held */
.btn, .icon-btn, .tile, .who-card, .person-card, .rail-card,
.tabbar-item, .pill-nav a, .nav-link, .tenant-pick .box,
[data-pressable], [data-tap-href] {
  transition: transform 160ms cubic-bezier(.2, .8, .3, 1), filter 160ms ease;
}
a { transition: opacity 160ms ease; }

/* ---- the page that is on its way -------------------------------------- */
/*
  One hairline along the very top edge, above everything including the nav.
  It creeps to nine tenths and waits there: the last tenth is the new page
  painting over it, which is the only honest way for it to finish. Nothing
  ever fills it to 100% and lies.
*/
.page-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 300;
  pointer-events: none;
  background: transparent;
}
.page-progress i {
  display: block;
  height: 100%;
  width: 4%;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(90deg, var(--accent), var(--accent));
  box-shadow: 0 0 10px var(--accent);
  transition: width 9s cubic-bezier(.05, .7, .1, 1);
}
.page-progress.go i { width: 92%; }

/* ---- a form that has been sent says so -------------------------------- */
/*
  The commonest double payment is a second tap on a Save button that gave no
  sign of the first. /js/touch.js marks the button the moment its form is on
  its way, and blocks the second submit outright.
*/
.is-busy {
  opacity: .65;
  pointer-events: none;
  position: relative;
}
.is-busy::after {
  content: '';
  position: absolute;
  right: 12px;
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: touchSpin .6s linear infinite;
}
@keyframes touchSpin { to { transform: rotate(360deg); } }

/* ---- and now the parts that are only right without a mouse ------------ */
@media (hover: none), (pointer: coarse) {

  /* hover stops pretending to be a state */
  /*
    These all lift or recolour on :hover in style.css and the panel views.
    On touch that lift is applied on tap and never taken back, which is why
    a list can end up with three cards apparently raised at once.
  */
  .tile:hover,
  .who-card:hover,
  .tenant-pick:hover .box,
  .person-card:hover,
  .rail-card:hover,
  .stat-card:hover {
    transform: none;
  }

  /*
    A tap should never leave a blue flash, a text selection or a magnifier
    behind it. Inputs are deliberately left out: text there is meant to be
    selectable, and touch-action must stay free for the caret.
  */
  .btn, .icon-btn, .tile, .who-card, .person-card, .rail-card, .tabbar-item,
  .pill-nav a, .nav-link, .tenant-pick, .seg label, .years label, summary,
  button, [data-pressable], [data-tap-href] {
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    touch-action: manipulation;
  }
  /* a link keeps its selectable text, but loses the grey flash */
  a { -webkit-tap-highlight-color: transparent; }

  /* thumb-sized targets */
  /*
    44px is the smallest thing a thumb hits reliably first time. Height is
    given as min-height so nothing already taller shrinks, and the padding
    is left alone so the type stays where the design put it.
  */
  .btn, .icon-btn, .pill-nav a, .nav-link,
  select, input:not([type=checkbox]):not([type=radio]), textarea, summary {
    min-height: 44px;
  }
  .btn, .icon-btn, .pill-nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .btn-sm { min-height: 40px; }
  .icon-btn { min-width: 44px; }

  /*
    The seg and years pickers are the two places a wrong tap costs the most
    - paid vs not yet, one year vs three - so they get the full height and
    the labels stop touching each other.
  */
  .seg span { min-height: 44px; display: flex; align-items: center; }
  .years span { min-height: 44px; display: flex; align-items: center; justify-content: center; }

  /*
    A checkbox or radio is a 13px square with a label beside it. The square
    is not the target: the row is.
  */
  label.check, .tenant-pick label, .form-group label.check {
    min-height: 44px;
    display: flex;
    align-items: center;
    gap: 10px;
  }

  /*
    The quiet inline buttons - "Resend the link", "Change the address", the
    actions inside an alert - are text with no box, so they are given room
    around them rather than a border they were never meant to have.
  */
  .alert button, .alert a, .alert .note-action, .confirm-strip .acts button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /*
    A row of quiet links under a name - Message, Payment, Lease, History -
    is four six-character targets in a line. They keep their look and gain
    the height a thumb needs.
  */
  .who-row .acts a, .unit-panel .row-acts a, .prop-units .more a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }

  /* whole rows and cards, rather than the link inside them */
  /*
    The dead zone in a list is the 90% of the row that is not the six
    characters of the link. Anything carrying data-tap-href is tappable edge
    to edge (/js/touch.js does the navigating), and .tap-through is the
    pure-CSS version for a card that already contains its own link.
  */
  [data-tap-href] { cursor: pointer; }

  .tap-through { position: relative; }
  .tap-through a.tap-main::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
  }
  /* anything else in the card that can be tapped stays above that sheet */
  .tap-through .btn,
  .tap-through button,
  .tap-through a:not(.tap-main),
  .tap-through input,
  .tap-through select,
  .tap-through summary { position: relative; z-index: 2; }

  /* a rail scrolls like a rail */
  .rail, .scroll-rail, .tenant-grid, .who-cards {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
}

/*
  Somebody who has asked their phone to stop animating gets the colour
  change and none of the movement. The feedback is the point, not the
  motion, so it is the scale that goes.
*/
@media (prefers-reduced-motion: reduce) {
  .is-pressed { transform: none; }
  .is-busy::after { animation: none; }
  .page-progress i { transition: none; }
}
