/*
 * Disable preflight styles:
 * https://tailwindcss.com/docs/preflight#disabling-preflight
 */
@layer theme, base, components, utilities;

@import 'tailwindcss/theme.css' layer(theme) prefix(tp);
@import 'tailwindcss/utilities.css' layer(utilities) prefix(tp) source('./');

@import '../../../css/themes.css' layer(base);

@custom-variant no-overlay ([data-type="window"]:not([data-has-overlay]) &);
@custom-variant has-overlay ([data-type="window"][data-has-overlay] &);

@theme {
  --animate-flash: flash 0.5s;

  @keyframes flash {
    from {
      background: white;
      color: white;
    }
  }
}

@theme {
  --color-black: #1d1a19;
  --color-overlay-gray: oklch(0.5697 0.0174 37.83);

  --shadow-overlay-button:
    0.2px 0.6px 0.5px hsl(0deg 0% 0% / 12%),
    0.4px 1.2px 1.1px -1.5px hsl(0deg 0% 0% / 9%),
    1.4px 3.7px 3.3px -3px hsl(0deg 0% 0% / 6%),
    3.8px 10.3px 9.1px -4.4px hsl(0deg 0% 0% / 4%);
}

/*
 * Theme variables referencing other variables have to be inlined, otherwise,
 * updates to the referenced variables will not propagate as expected.
 * See https://tailwindcss.com/docs/theme#referencing-other-variables
 */
@theme inline {
  /**
   * Compare to
   * https://github.com/tailwindlabs/tailwindcss/blob/48957c541122f77ff22a09f81545b14ae7d7ae80/packages/tailwindcss/theme.css#L299-L324
   */
  --text-2xs: calc(10 / 14 * var(--base-font-size));
  --text-2xs--line-height: calc(0.9 * var(--base-font-size));
  --text-xs: calc(11 / 14 * var(--base-font-size));
  --text-xs--line-height: var(--base-font-size);
  --text-sm: calc(12 / 14 * var(--base-font-size));
  --text-sm--line-height: calc(1.25 * var(--base-font-size));
  --text-smish: calc(13 / 14 * var(--base-font-size));
  --text-smish--line-height: calc(1.4 * var(--base-font-size));
  --text-base: var(--base-font-size);
  --text-base--line-height: calc(1.5 * var(--base-font-size));
  --text-lg: calc(16 / 14 * var(--base-font-size));
  --text-lg--line-height: calc(1.75 * var(--base-font-size));
  --text-xl: calc(18 / 14 * var(--base-font-size));
  --text-xl--line-height: calc(1.75 * var(--base-font-size));
  --text-1.5xl: calc(20 / 14 * var(--base-font-size));
  --text-1.5xl--line-height: calc(1.85 * var(--base-font-size));
  --text-2xl: calc(22 / 14 * var(--base-font-size));
  --text-2xl--line-height: calc(2 * var(--base-font-size));
  --text-big-kanji: calc(60 / 14 * var(--base-font-size));
  --text-big-kanji--line-height: 1;

  --spacing: calc(0.25 * var(--base-font-size));

  --radius-xs: calc(0.125 * var(--base-font-size));
  --radius-sm: calc(0.25 * var(--base-font-size));
  --radius-md: calc(0.375 * var(--base-font-size));
  --radius-lg: calc(0.5 * var(--base-font-size));
  --radius-xl: calc(0.75 * var(--base-font-size));
  --radius-2xl: calc(1.25 * var(--base-font-size));
  --radius-3xl: calc(1.5 * var(--base-font-size));
}

@utility stacked {
  display: grid;

  & > * {
    grid-area: 1 / 1 / 2 / 2;
  }
}

/*
 * TODO Convert the following to more Tailwind-like utilities.
 */
@layer components {
  :host {
    /*
     * The following is because there appears to be some (yet unidentified)
     * add-on that sets `position: absolute` on various div elements. As a
     * result, our popup will end up being positioned at the very end of the
     * page unless we ensure we set left/top ourselves.
     *
     * See: https://github.com/birchill/10ten-ja-reader/issues/947
     */
    position: revert !important;

    /*
     * However, supposing our rule above loses out to the interfering add-on?
     *
     * Assuming said add-on sets `position: absolute` on the popup we can make it
     * work for us by setting the left/top/bottom/right properties.
     */
    position: absolute !important;
    left: 0 !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    pointer-events: none !important;

    /*
     * It's conceivable add-ons might interfere with our z-index too so make
     * sure that's covered.
     */
    z-index: 2147483647 !important;
  }

  :root,
  :host {
    --normal-font-size: 14px;
    --large-font-size: 17px;
    --xl-font-size: 19px;

    --base-font-size: var(--normal-font-size);
  }

  .container {
    position: absolute;
    left: var(--tenten-left, auto);
    top: var(--tenten-top, auto);

    /*
    * Use the empirical maximum z-index since some sites (e.g. TimeTree) use this
    * for their popups.
    */
    z-index: 2147483647;

    /* Make sure the drop shadow on the window doesn't get cut off */
    padding-right: 4px;
    padding-bottom: 4px;

    overflow-y: visible;
    pointer-events: all;
  }

  .container:not(.interactive) {
    pointer-events: none;
  }

  /*
  * Variation on the interactive container when it is not yet actually
  * interactive.
  */
  .container.interactive.ghost {
    pointer-events: none;
  }

  .container.interactive.ghost .window {
    border-style: dashed;
  }

  .container.hidden {
    display: none;
  }

  .-inline > .container {
    position: revert;
    z-index: revert;
    pointer-events: revert;
  }

  /*
  * When the popup is interactive we make the window scrollable, but for
  * non-interactive cases we just fade it out.
  *
  * To make the window scrollable we need to set the max-height on the
  * window itself.
  *
  * For the fade-effect, however, we set the max-height and fade effect
  * on the container so that the mask doesn't end up clipping the drop shadow
  * on the popup.
  */
  .container.interactive .window {
    max-height: var(--tenten-max-height, none);
  }

  .container:not(.interactive) {
    max-height: var(--tenten-max-height, none);
    -webkit-mask-image: linear-gradient(
      to bottom,
      black calc(var(--tenten-max-height) - 5px),
      transparent
    );
    mask-image: linear-gradient(
      to bottom,
      black calc(var(--tenten-max-height) - 5px),
      transparent
    );
  }

  .container .window {
    min-height: var(--tenten-min-height, none);
  }

  .window {
    max-width: var(--tenten-max-width, 600px);
    max-width: var(--tenten-max-width, min(600px, calc(100vw - 30px)));

    contain: content;
    border-radius: 5px;
    box-shadow:
      0px 0.5px 0.5px rgba(100, 100, 100, 0.15),
      1px 2px 1px rgba(100, 100, 100, 0.15),
      2px 4px 8px rgba(100, 100, 100, 0.15);
    font: normal 14px;

    color: var(--text-color);
    background: var(--bg-color);
    border: 1px solid var(--border-color);

    font-family: Meiryo, sans-serif;
  }

  .window.bundled-fonts {
    font-family: '10ten Inter', '10ten Noto Sans JP', sans-serif;
    font-feature-settings:
      'calt', 'case', 'cv01', 'cv03', 'cv04', 'cv11', 'ss03';
    font-weight: 380;
  }

  /* When the tabs are shown on top, make the window have a consistent width
    so the tabs don't jump around. */
  .window[data-tab-side='top'] {
    display: flex;
    max-width: none;
    /* Fallback for the below */
    width: 500px;
    /* The 30px here is to accommodate scrollbars on Windows plus a bit of
      padding. */
    width: min(500px, calc(100vw - 30px));
  }

  .container:not(.hidden) .window {
    display: flex;
    flex-direction: column;
  }

  .container.interactive .content {
    overflow: auto;
    overscroll-behavior: contain;
  }

  @supports (scrollbar-width: thin) {
    .window .content {
      scrollbar-width: thin;
      scrollbar-color: var(--scrollbar-fg) var(--scrollbar-bg);
    }
  }

  @supports not (scrollbar-width: thin) {
    .window .content::-webkit-scrollbar {
      width: 7px;
      background-color: var(--scrollbar-bg);
    }

    .window .content::-webkit-scrollbar-thumb {
      background-color: var(--scrollbar-fg);
    }
  }

  .window .status-bar-wrapper {
    flex-grow: 1;

    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .window .status-bar-wrapper > :first-child {
    flex-grow: 1;
  }

  .window .status-bar-wrapper > .status-bar {
    flex-shrink: 0;
  }

  .window .content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
  }

  .window .content > :first-child {
    flex-grow: 1;
  }

  .window {
    font-size: var(--base-font-size);
  }

  .window.font-large {
    --base-font-size: var(--large-font-size);
  }

  .window.font-xl {
    --base-font-size: var(--xl-font-size);
  }

  /* Tab bar */

  .tab-bar {
    flex-shrink: 0;

    display: flex;
    padding: 0;
    margin: 0;
    /* Safari appears to need the following */
    overflow: hidden;

    background: var(--cell-highlight-bg);
    color: var(--cell-highlight-fg);

    /* Make sure we are above the content area. This is mostly needed when we are
    * showing the copy overlay since the entry data might overflow its region in
    * that case. */
    z-index: 1;
  }

  .tabs {
    flex-grow: 1;
    display: flex;
    padding: 0;
    margin: 0;
  }

  .tabs .tab {
    flex-grow: 1;
    list-style: none;
    font-size: calc(var(--base-font-size) * 0.8);
    -webkit-user-select: none;
    user-select: none;
  }

  /* Make the tabs bigger in interactive mode so they are easier to click */
  .container.interactive .tabs .tab {
    font-size: var(--base-font-size);
  }

  /* Don't increase the tab font size too much or else it looks childish */
  .window.font-large .tabs .tab,
  .window.font-xl .tabs .tab {
    font-size: calc(var(--base-font-size) * 0.8);
  }

  .tabs .tab button {
    /* Reset button styles */
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    margin: 0;
    border: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;

    opacity: 0.7;
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0.5em 18px;
    line-height: 1;
    text-decoration: none;
  }

  @media (max-width: 400px) {
    .window[data-tab-side='top'] .tabs .tab button span:lang(en) {
      font-size: calc(var(--base-font-size) * 0.7);
    }
  }

  @media (max-width: 350px) {
    .window[data-tab-side='top'] .tabs .tab {
      flex-grow: 0;
    }
    .window[data-tab-side='top'] .tabs .tab button span {
      display: none;
    }
    .window[data-tab-side='top'] .tabs .tab button .icon {
      margin-right: 0px;
    }
  }

  .container.interactive .tabs .tab button {
    padding: 0.7em 18px;
  }

  .tabs .tab button .icon {
    display: block;
    width: 12px;
    height: 12px;
    margin-right: 5px;
    /* Push the icon up a little so it looks more aligned with the text */
    margin-bottom: 1px;
    fill: currentcolor;
  }

  .container.interactive .tabs .tab button .icon {
    width: 14px;
    height: 14px;
  }

  .tabs .tab[aria-selected] {
    background: var(--bg-color);
  }

  .tabs .tab[aria-selected] button {
    color: var(--text-color);
  }

  .tabs .tab:not([aria-selected]) button {
    opacity: 0.8;
    color: var(--cell-highlight-fg);
  }

  .tabs .tab:not([aria-selected]):hover {
    filter: brightness(1.1);
  }

  .tabs .tab:not([aria-selected]):hover button {
    opacity: 1;
  }

  .tabs .tab.disabled {
    opacity: 0.3;
    pointer-events: none;
  }

  .container:not(.interactive) .settings,
  .container:not(.interactive) .pin,
  .container:not(.interactive) .close {
    display: none;
  }

  .tab-bar .settings,
  .tab-bar .pin,
  .tab-bar .close {
    flex-shrink: 0;
    align-self: center;
    margin: 2px;
  }

  .window .close-button-wrapper {
    flex-grow: 1;

    display: flex;
    overflow: auto;
  }

  .window .close-button-wrapper .close {
    z-index: 1;
    flex: 0 0 auto;
    margin: 4px;
    /* Drop margin since the meta element should have sufficient padding */
    margin-left: 0px;
  }

  /*
  * The following uses .close .close-button because we have two configurations:
  * a) The close button is a child of the tab bar
  * b) The close button is a child of the close-button-wrapper
  */
  .settings-button,
  .pin-button,
  .close .close-button {
    appearance: none;
    border: none;
    line-height: 1;
    padding: 6px;
    border-radius: 20px;
    color: var(--text-color);
  }

  .settings-button,
  .pin-button {
    cursor: pointer;
    background: transparent;
  }

  .settings-button:hover,
  .pin-button:hover,
  .close .close-button {
    background: var(--bg-color);
  }

  .settings-button:hover,
  .pin-button:hover,
  .close .close-button:hover {
    filter: brightness(1.1);
  }

  .settings-button svg,
  .pin-button svg,
  .close .close-button svg {
    display: block;
    width: 15px;
    height: 15px;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-opacity: 0.7;
    fill-opacity: 0.7;
    fill: none;
  }

  .settings-button svg,
  .pin-button svg {
    stroke-width: 2px;
  }

  .close .close-button svg {
    stroke-width: 5px;
  }

  .settings-button:hover svg,
  .pin-button:hover svg,
  .close .close-button:hover svg {
    stroke-opacity: 1;
    fill-opacity: 1;
  }

  .container.pinned .pin-button svg path {
    fill: currentColor;
  }

  /* Tab bar on the side */

  .container:not(.hidden) .window[data-tab-side='left'],
  .container:not(.hidden) .window[data-tab-side='right'] {
    display: flex;
    flex-direction: row;
  }

  .container .window[data-tab-side='left'] .tab-bar,
  .container .window[data-tab-side='right'] .tab-bar {
    flex-direction: column;
    overflow: visible;
  }

  .container .window[data-tab-side='right'] .tab-bar {
    order: 1;
  }

  .container .window[data-tab-side='left'] .tab-bar .tabs,
  .container .window[data-tab-side='right'] .tab-bar .tabs {
    display: flex;
    flex-direction: column;
  }

  .container .window[data-tab-side='left'] .tab-bar .settings,
  .container .window[data-tab-side='right'] .tab-bar .settings {
    margin-bottom: 0.5em;
  }

  .container .window[data-tab-side='top'] .tab-bar .close {
    margin-left: 1em;
  }

  .container .window[data-tab-side='left'] .tab-bar .close,
  .container .window[data-tab-side='right'] .tab-bar .close {
    order: -1;
    margin-top: 0.5em;
    margin-bottom: 1em;
  }

  .container .window[data-tab-side='left'] .tabs .tab,
  .container .window[data-tab-side='right'] .tabs .tab {
    flex-grow: 0;
  }

  .container .window[data-tab-side='left'] .tabs .tab button,
  .container .window[data-tab-side='right'] .tabs .tab button {
    padding: 0.7em;
  }

  .container .window[data-tab-side='left'] .tabs .tab button svg,
  .container .window[data-tab-side='right'] .tabs .tab button svg {
    margin: 0;
  }

  .container .window[data-tab-side='left'] .tabs .tab button span,
  .container .window[data-tab-side='right'] .tabs .tab button span {
    display: none;
  }

  /* Expandable container */

  .window .content .expandable {
    overflow: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
  }

  @supports (scrollbar-width: thin) {
    .window .content .expandable {
      scrollbar-width: thin;
      scrollbar-color: var(--scrollbar-fg) var(--scrollbar-bg);
    }
  }

  @supports not (scrollbar-width: thin) {
    .window .content .expandable::-webkit-scrollbar {
      width: 7px;
      background-color: var(--scrollbar-bg);
    }

    .window .content .expandable::-webkit-scrollbar-thumb {
      background-color: var(--scrollbar-fg);
    }
  }

  .window .content .expandable .fold-point {
    display: contents;
  }

  /* Expand button */

  .window .content .expand-button {
    /* Box layout */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 8px;

    /* Positioning */
    position: sticky;
    bottom: 0;

    /* Reset button styles */
    appearance: none;
    border: 0;
    margin: 0;
    cursor: pointer;
    font: inherit;
    line-height: 1;
    text-decoration: none;

    /* Colors */
    background: linear-gradient(
      to bottom,
      rgba(var(--bg-rgb), 0.3),
      var(--bg-color) 80%
    );
    color: rgba(var(--expand-button-rgb), 0.8);
  }

  .window .content {
    /* Extra space to add to the end of the content so the expand button doesn't
    * overlap with the last entry. */
    --expand-button-allowance: 35px;
  }

  .window .content .expand-button:hover {
    color: var(--expand-button-color);
    /* Use outline instead of border so it doesn't affect the layout (even if we
    * try to reserve space for the border using a transparent border it will not
    * blend with the underlying element since you can't have a fully transparent
    * border on a non-transparent background. */
    outline: 1px var(--expand-button-color) dotted;
    background: linear-gradient(
      to bottom,
      rgba(var(--bg-rgb), 0.8),
      var(--bg-color) 80%
    );
  }

  .window .content .expand-button .icon {
    width: 16px;
    height: 16px;
    flex-grow: 1;
  }

  .window .content .expand-button kbd {
    color: var(--expand-button-color);
    font-family: monospace;
    font-weight: 800;
    padding: 0.1rem 0.2rem;
    border-radius: 0.2rem;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid var(--expand-button-color) !important;
  }

  /* Kanji display */

  .kanjilist {
    /*
    * Make each kanji item have the same height so that when we scroll the next
    * one into view it fits.
    */
    display: grid;
    grid-auto-rows: 1fr;
  }

  /*
   * If the list has been expanded, however, there is no need to space the kanji
   * items out evenly.
   */
  .expandable.expanded .kanjilist {
    grid-auto-rows: auto;
  }

  /*
   * Status bar
   */

  .status-bar {
    position: relative;
    width: 100%;
    background: var(--status-bg);
    max-height: calc(4 * var(--base-font-size));
  }

  .window.font-xl .status-bar {
    font-size: calc(0.8 * var(--base-font-size));
  }

  .status-bar > .status {
    display: flex;
    align-items: baseline;
  }

  .status-bar > * {
    padding: 5px 8px 5px;
  }

  .status-bar.-subdued {
    opacity: 0.7;
  }

  .status-bar kbd {
    color: rgb(10, 10, 10);
    font-size: 0.8em;
    font-family: monospace;
    height: 1.2rem;
    padding: 0.2rem;
    border-radius: 0.2rem;
    background: white;
    border: 1px solid #909090 !important;
  }

  .status-bar .spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-right: 7px;
    fill: currentcolor;
    animation: spin-ccw 0.8s linear infinite;
  }

  .window.-copy-finished .status-bar > .keys,
  .window.-copy-error .status-bar > .keys {
    animation: fade-out 0.4s linear forwards;
  }

  .window.-copy-finished .status-bar > .status {
    opacity: 0;
    animation:
      fade-in 0.4s linear forwards,
      fade-out 0.3s 0.9s forwards;
  }

  .window.-copy-finished .status-bar {
    animation: roll-up 0.3s 1s forwards;
  }

  @keyframes fade-out {
    to {
      opacity: 0;
    }
  }

  @keyframes fade-in {
    to {
      opacity: 1;
    }
  }

  @keyframes roll-up {
    to {
      max-height: 0;
    }
  }

  @keyframes spin-ccw {
    to {
      transform: rotate(-360deg);
    }
  }

  .window.-copy-error .status-bar > .status {
    opacity: 0;
    animation: fade-in 0.4s linear forwards;
    background: rgba(255, 204, 204, 0.8);
    color: #b43e3e;
  }

  /*
   * Arrow
   */
  .arrow {
    position: absolute;
    overflow: hidden;

    /* Desired width of the arrow */
    --arrow-width: 20px;

    /*
    * Amount of room to allow for the shadow.
    */
    --shadow-radius: 8px;
    --shadow-margin: calc(var(--shadow-radius) / 2);

    /*
    * Crop the arrow region to show half the arrow plus allow room for margins.
    */
    width: calc(var(--arrow-width) + 2 * var(--shadow-margin));
    height: calc(var(--arrow-width) / 2 + var(--shadow-margin));

    z-index: 2147483647;
  }

  .arrow.-left,
  .arrow.-right {
    width: calc(var(--arrow-width) / 2 + var(--shadow-margin));
    height: calc(var(--arrow-width) + 2 * var(--shadow-margin));
  }

  .arrow::before {
    position: absolute;
    content: '';

    /* Make sure the border is included in the size. */
    box-sizing: border-box;

    /* Don't inherit any rounded corners. */
    border-radius: 0;

    /*
    * When the box is rotated, it should have width <arrow-width>. That makes the
    * length of one side of the box equal to:
    *
    *    (<arrow-width> / 2) / sin 45
    */
    --sin-45: 0.707106781;
    --square-side: calc(var(--arrow-width) / 2 / var(--sin-45));
    width: var(--square-side);
    height: var(--square-side);

    /*
    * The rotated square will overshoot the left / top side and need to be
    * shifted in by:
    *
    *   (<arrow-width> - <square side>) / 2
    *
    * But we also want to shift it in so that the box-shadow is not clipped when
    * we clip the parent so we add a suitable margin for that.
    */
    --overhang: calc((var(--arrow-width) - var(--square-side)) / 2);
    margin-left: calc(var(--overhang) + var(--shadow-margin));
    margin-top: calc(var(--overhang) + var(--shadow-margin));

    background: var(--bg-color);
    border: 1px solid var(--border-color);
  }

  .arrow.-bottom {
    margin-top: -1px;
  }

  .arrow.-bottom::before {
    transform: rotate(45deg);
    margin-top: calc(var(--square-side) / -2);
    box-shadow:
      0px 0.5px 0.5px rgba(100, 100, 100, 0.15),
      2px 2px 1px rgba(100, 100, 100, 0.15),
      4px 4px 8px rgba(100, 100, 100, 0.15);
  }

  .arrow.-top {
    margin-top: 1px;
  }

  .arrow.-top::before {
    transform: rotate(225deg);
    box-shadow:
      0px 0.5px 0.5px rgba(100, 100, 100, 0.15),
      -1px 2px 1px rgba(100, 100, 100, 0.15);
  }

  .arrow.-right {
    margin-left: -1px;
  }

  .arrow.-right::before {
    transform: rotate(225deg);
    margin-left: calc(var(--square-side) / -2);
    box-shadow:
      0px 0.5px 0.5px rgba(100, 100, 100, 0.15),
      -2px 2px 1px rgba(100, 100, 100, 0.15),
      -2px 2px 8px rgba(100, 100, 100, 0.15);
  }

  .arrow.-left {
    margin-left: 1px;
  }

  .arrow.-left::before {
    transform: rotate(45deg);
  }
}
