/* ========================================================================== Brew Log — design system Beer-house palette: warm amber/copper on near-black, with a condensed display face (Anton) for headings and Inter for everything else. Palette taken from the brewery-128 template: --primary #be7f39 (amber / copper) --primary-dark #0e0e0e --black-primary #212024 --black-secondary #161616 --gray #e9e9e9 --dark-gray #afafaf --paragraph-gray #535353 ========================================================================== */ /* ------------------------------------------------------------------ fonts */ @font-face { font-family: 'Anton'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/anton-latin.woff2') format('woff2'); } @font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap; src: url('../fonts/inter-latin-400.woff2') format('woff2'); } /* ----------------------------------------------------------------- tokens */ :root { /* surfaces */ --bg: #121110; --bg-raised: #1c1a19; --bg-raised-2: #242120; --bg-input: #161514; /* lines */ --border: #332e2a; --border-strong: #4a4239; /* text */ --text: #f2ede8; --text-muted: #afafaf; --text-faint: #7d746c; /* brand */ --amber: #be7f39; --amber-bright: #dda05c; --amber-deep: #8f5f28; --amber-dim: rgba(190, 127, 57, 0.14); --amber-text: #e2b47c; /* foam / highlights */ --foam: #f7f3ee; --cream: #eef4f8; /* status */ --warn: #e8a33d; --warn-dim: rgba(232, 163, 61, 0.14); --danger: #d9534f; --danger-dim: rgba(217, 83, 79, 0.14); --success: #7db902; --success-dim: rgba(125, 185, 2, 0.14); --radius: 10px; --radius-sm: 6px; --radius-lg: 16px; --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 30px rgba(0, 0, 0, .35); --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; --display: 'Anton', 'Arial Narrow', Impact, sans-serif; --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace; } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text); font-family: var(--font); font-size: 15px; line-height: 1.55; -webkit-font-smoothing: antialiased; } a { color: var(--amber-text); text-decoration: none; } a:hover { text-decoration: underline; } h1, h2, h3, h4 { margin: 0 0 .5rem; line-height: 1.15; font-weight: 650; } h1 { font-size: 1.65rem; } h2 { font-size: 1.25rem; } h3 { font-size: 1.02rem; } p { margin: 0 0 .75rem; } /* Display type: the condensed face, used sparingly for headings and figures. */ .display { font-family: var(--display); font-weight: 400; letter-spacing: .01em; text-transform: uppercase; } /* ---------------------------------------------------------------- topbar */ .topbar { position: sticky; top: 0; z-index: 50; background: rgba(18, 17, 16, .94); backdrop-filter: blur(8px); border-bottom: 1px solid var(--border); } .topbar__inner { max-width: 1240px; margin: 0 auto; padding: .6rem 1.25rem; display: flex; align-items: center; gap: 1.5rem; } .brand { display: flex; align-items: center; gap: .55rem; color: var(--text); text-decoration: none; } .brand:hover { text-decoration: none; } .brand__mark { font-size: 1.4rem; line-height: 1; filter: drop-shadow(0 0 10px rgba(190, 127, 57, .35)); } .brand__text { font-family: var(--display); font-size: 1.22rem; letter-spacing: .04em; text-transform: uppercase; color: var(--amber-bright); } .nav { display: flex; gap: .25rem; flex: 1; } .nav__link { padding: .4rem .8rem; border-radius: var(--radius-sm); color: var(--text-muted); font-size: .92rem; font-weight: 500; text-decoration: none; transition: background .12s ease, color .12s ease; } .nav__link:hover { background: var(--bg-raised-2); color: var(--text); text-decoration: none; } .nav__link.is-active { background: var(--amber-dim); color: var(--amber-text); box-shadow: inset 0 -2px 0 var(--amber); } .topbar__logout { display: flex; align-items: center; gap: .6rem; } .topbar__user { color: var(--text-muted); font-size: .85rem; font-family: var(--mono); padding: .15rem .5rem; border: 1px solid var(--border); border-radius: 999px; } /* ------------------------------------------------------------------ page */ .page { max-width: 1240px; margin: 0 auto; padding: 1.5rem 1.25rem 4rem; } .page--narrow { max-width: 460px; } .page__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; } .page__title { margin: 0; font-family: var(--display); font-weight: 400; font-size: 1.85rem; letter-spacing: .02em; text-transform: uppercase; color: var(--text); } .page__sub { color: var(--text-muted); font-size: .9rem; margin: .15rem 0 0; } /* ----------------------------------------------------------------- cards */ .card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); position: relative; } /* A thin amber seam along the top of each card — the "label on the barrel" touch. */ .card::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 2px; border-radius: var(--radius) var(--radius) 0 0; background: linear-gradient(90deg, var(--amber-deep), var(--amber) 40%, transparent 85%); opacity: .8; } .card__head { padding: .9rem 1.1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; } .card__title { margin: 0; font-size: 1rem; font-weight: 650; letter-spacing: .01em; } .card__hint { color: var(--text-faint); font-size: .82rem; } .card__body { padding: 1.1rem; } .card__body--flush { padding: 0; } .grid { display: grid; gap: 1rem; } .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* The active-beer cards: fill the row whatever the number of brews. */ .grid--cards { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); } .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } .grid--sidebar { grid-template-columns: minmax(0, 380px) minmax(0, 1fr); align-items: start; } @media (max-width: 1000px) { .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid--sidebar { grid-template-columns: minmax(0, 1fr); } } @media (max-width: 640px) { .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); } .topbar__inner { flex-wrap: wrap; gap: .75rem; } .nav { order: 3; width: 100%; overflow-x: auto; } .page__title { font-size: 1.5rem; } } /* ----------------------------------------------------------------- stats */ .stat { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); padding: .85rem 1rem; } .stat__label { color: var(--text-faint); font-size: .72rem; text-transform: uppercase; letter-spacing: .09em; font-weight: 600; } .stat__value { font-family: var(--display); font-weight: 400; font-size: 1.75rem; letter-spacing: .02em; line-height: 1.2; color: var(--amber-bright); } .stat__meta { color: var(--text-muted); font-size: .83rem; } /* ----------------------------------------------------------------- forms */ .field { margin-bottom: .9rem; } .field__label { display: block; font-size: .74rem; font-weight: 600; text-transform: uppercase; letter-spacing: .09em; color: var(--text-muted); margin-bottom: .3rem; } .field__hint { color: var(--text-muted); font-size: .8rem; margin-top: .25rem; } .field__error { color: var(--danger); font-size: .8rem; margin-top: .25rem; } input[type="text"], input[type="password"], input[type="number"], input[type="date"], input[type="email"], textarea, select { width: 100%; padding: .5rem .65rem; background: var(--bg-input); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); color: var(--text); font-family: inherit; font-size: .92rem; transition: border-color .12s ease, box-shadow .12s ease; } input:focus, textarea:focus, select:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-dim); } input::placeholder, textarea::placeholder { color: var(--text-faint); } textarea { resize: vertical; min-height: 5rem; } .checkbox { display: flex; align-items: center; gap: .55rem; font-size: .9rem; color: var(--text); cursor: pointer; } /* The native checkbox is a white square on a near-black page — replace it. */ .checkbox input[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 1.05rem; height: 1.05rem; margin: 0; flex: 0 0 auto; border: 1px solid var(--border-strong); border-radius: 4px; background: var(--bg-input); cursor: pointer; position: relative; transition: background .12s ease, border-color .12s ease; } .checkbox input[type="checkbox"]:hover { border-color: var(--amber); } .checkbox input[type="checkbox"]:checked { background: var(--amber); border-color: var(--amber); } .checkbox input[type="checkbox"]:checked::after { content: ''; position: absolute; left: .32rem; top: .07rem; width: .28rem; height: .55rem; border: solid #17110a; border-width: 0 2px 2px 0; transform: rotate(43deg); } .checkbox input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--amber-dim); } /* Hide the native number spinners — the light spinner widgets jar badly against the dark theme. */ input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type="number"] { -moz-appearance: textfield; } /* The native date picker's calendar icon is near-black on near-black. */ input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.75) sepia(1) saturate(3) hue-rotate(350deg) brightness(1.1); cursor: pointer; opacity: .7; } input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; } /* Dark scrollbars to match the page. */ * { scrollbar-width: thin; scrollbar-color: var(--border-strong) var(--bg); } ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: var(--bg); } ::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 6px; border: 2px solid var(--bg); } ::-webkit-scrollbar-thumb:hover { background: var(--amber-deep); } /* A figure that should read as a number, not as body text. */ .strong { font-weight: 650; color: var(--text); } .field-row { display: flex; gap: .75rem; } .field-row > * { flex: 1; } /* --------------------------------------------------------------- buttons */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; padding: .5rem .95rem; border: 1px solid transparent; border-radius: var(--radius-sm); background: var(--amber); color: #17110a; font-family: inherit; font-size: .85rem; font-weight: 650; letter-spacing: .01em; cursor: pointer; text-decoration: none; transition: filter .12s ease, background .12s ease, border-color .12s ease; } .btn:hover { filter: brightness(1.12); text-decoration: none; } .btn:disabled { opacity: .5; cursor: not-allowed; } .btn--ghost { background: transparent; border-color: var(--border-strong); color: var(--text-muted); } .btn--ghost:hover { background: var(--bg-raised-2); color: var(--text); } .btn--danger { background: transparent; border-color: var(--danger); color: var(--danger); } .btn--danger:hover { background: var(--danger-dim); } .btn--sm { padding: .3rem .6rem; font-size: .78rem; } .btn--block { width: 100%; } .btn-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; } /* ---------------------------------------------------------------- tables */ .table-wrap { overflow-x: auto; } table.data { width: 100%; border-collapse: collapse; font-size: .88rem; } table.data th { text-align: left; padding: .55rem .8rem; color: var(--text-faint); font-size: .7rem; font-weight: 650; text-transform: uppercase; letter-spacing: .08em; border-bottom: 1px solid var(--border); background: var(--bg-raised-2); white-space: nowrap; } table.data td { padding: .6rem .8rem; border-bottom: 1px solid var(--border); vertical-align: top; } table.data tr:last-child td { border-bottom: none; } table.data tbody tr:hover { background: var(--bg-raised-2); } table.data .num { font-family: var(--mono); text-align: right; white-space: nowrap; } table.data .comment { color: var(--text-muted); font-size: .84rem; } /* On a narrow screen the tables reflow into stacked cards. A seven-column table does not fit a phone. It was left to scroll sideways inside its wrapper, which meant the columns on the right were off the screen and the brewer had to pan the table to see them. Each row becomes a card: the header cell becomes a label above its value, and the cells stack. */ @media (max-width: 720px) { /* The header wraps onto two rows on a phone: the brand and the sign-out on the first, the nav tabs on the second where they get the full width and scroll sideways if they still do not fit. They used to sit on one row with the brand and the sign-out, and the last tab was cut off mid-word. */ .topbar__inner { flex-wrap: wrap; row-gap: .5rem; } .brand { order: 1; } .topbar__logout { order: 2; margin-left: auto; } .nav { order: 3; flex: 1 0 100%; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; /* A fade at the right edge so a clipped tab reads as scrollable rather than broken. */ -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent 100%); mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent 100%); } .nav::-webkit-scrollbar { display: none; } .nav__link { flex-shrink: 0; } /* Tighter tabs, so all four fit on a phone without scrolling. They still scroll if they have to. */ .nav__link { padding: .35rem .55rem; font-size: .8rem; letter-spacing: .01em; } .table-wrap { overflow-x: visible; } table.data, table.data tbody, table.data tr, table.data td { display: block; width: auto; } table.data thead { /* HIDDEN in the stacked layout. Each cell shows its column name as a label, so the header row would be a duplicate - and it was 230px of the first card. */ display: none; } table.data tr { border: 1px solid var(--border); border-radius: 8px; margin-bottom: .75rem; padding: .25rem .1rem; background: var(--bg-raised-2); } table.data tbody tr:hover { background: var(--bg-raised-2); } table.data th { display: block; border-bottom: 1px solid var(--border); } table.data td { display: grid; grid-template-columns: 8.5rem 1fr; gap: .5rem; align-items: baseline; padding: .45rem .7rem; border-bottom: 1px solid rgba(255, 255, 255, .04); text-align: left; } table.data td::before { /* The column heading, shown as the row's label. */ content: attr(data-label); font-size: .65rem; font-weight: 650; letter-spacing: .07em; text-transform: uppercase; color: var(--text-faint); } table.data td.num { text-align: left; } table.data td.right, table.data td:empty { grid-template-columns: 1fr; } table.data td.right::before { content: none; } /* A cell with nothing in it must not leave a gap. */ table.data td:empty { display: none; } } /* ----------------------------------------------------------------- chips */ .chip { display: inline-flex; align-items: center; gap: .3rem; padding: .12rem .5rem; border-radius: 999px; font-size: .74rem; font-weight: 600; letter-spacing: .02em; white-space: nowrap; } .chip--active { background: var(--amber-dim); color: var(--amber-text); } .chip--done { background: rgba(175, 175, 175, .13); color: var(--text-muted); } .chip--warn { background: var(--warn-dim); color: var(--warn); } .chip--danger { background: var(--danger-dim); color: var(--danger); } .chip--good { background: var(--success-dim); color: var(--success); } /* A run whose readings are impossible: shown in the table so it can be corrected, but marked as not counted in the averages. */ .data tbody tr.is-suspect td { color: var(--text-muted); background: rgba(232, 163, 61, .06); } .chip--tap { background: var(--bg-raised-2); border: 1px solid var(--amber-deep); color: var(--amber-text); font-family: var(--mono); } /* --------------------------------------------------------------- flashes */ .flashes { display: flex; flex-direction: column; gap: .5rem; margin-bottom: 1rem; } .flash { padding: .6rem .9rem; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--bg-raised); font-size: .9rem; } .flash--success { border-color: rgba(125, 185, 2, .45); background: var(--success-dim); color: #c3e08a; } .flash--error { border-color: rgba(217, 83, 79, .45); background: var(--danger-dim); color: #f0a8a6; } .flash--warning { border-color: rgba(232, 163, 61, .45); background: var(--warn-dim); color: #f2c880; } .flash--info { border-color: rgba(190, 127, 57, .45); background: var(--amber-dim); color: var(--amber-text); } /* ---------------------------------------------------------------- login */ .login { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 2rem 1rem; background: radial-gradient(900px 480px at 50% -10%, rgba(190, 127, 57, .13), transparent 62%), var(--bg); } .login__card { width: 100%; max-width: 380px; background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 2rem; box-shadow: var(--shadow); position: relative; } .login__card::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 3px; border-radius: var(--radius-lg) var(--radius-lg) 0 0; background: linear-gradient(90deg, var(--amber-deep), var(--amber-bright), var(--amber-deep)); } .login__mark { font-size: 2.4rem; line-height: 1; } .login__title { margin: .6rem 0 .15rem; font-family: var(--display); font-weight: 400; font-size: 1.9rem; letter-spacing: .03em; text-transform: uppercase; color: var(--amber-bright); } .login__sub { color: var(--text-muted); font-size: .88rem; margin-bottom: 1.4rem; } /* ----------------------------------------------------------- active card */ .brew-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .75rem; position: relative; overflow: hidden; } .brew-card::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 2px; background: linear-gradient(90deg, var(--amber-deep), var(--amber) 45%, transparent 90%); opacity: .75; } .brew-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; } .brew-card__name { font-weight: 650; font-size: 1.02rem; margin: 0; } .brew-card__meta { color: var(--text-muted); font-size: .82rem; font-family: var(--mono); } .brew-card__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; } /* The three stats sit side by side, so their captions line up. One caption ("needs 2nd reading") is two lines and the others are one, which left the baselines ragged. */ .brew-card__stat { display: flex; flex-direction: column; } .brew-card__stat .stat__label { font-size: .68rem; } .brew-card__stat .stat__value { font-size: 1.3rem; } .brew-card__stat .stat__meta { margin-top: auto; } .brew-card__spark { height: 46px; } /* The "start a new beer" tile — fills the last grid slot and gives the page a way to begin a brew without hunting for the form. */ .brew-card--new { align-items: center; justify-content: center; gap: .6rem; text-align: center; text-decoration: none; color: var(--text-muted); border-style: dashed; border-color: var(--border-strong); min-height: 180px; } .brew-card--new:hover { border-color: var(--amber); color: var(--text); text-decoration: none; } .brew-card--new::before { display: none; } .brew-card__new-mark { display: flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; border: 1px solid var(--amber); border-radius: 50%; font-size: 1.35rem; line-height: 1; color: var(--amber); } .brew-card__new-text { display: flex; flex-direction: column; gap: .15rem; } .brew-card__new-text strong { font-size: .95rem; } .brew-card__spark--empty { display: flex; align-items: center; font-style: italic; padding: .35rem 0; } /* --------------------------------------------------------------- helpers */ .muted { color: var(--text-muted); } .faint { color: var(--text-faint); } .mono { font-family: var(--mono); } .nowrap { white-space: nowrap; } .small { font-size: .84rem; } .tiny { font-size: .76rem; } .center { text-align: center; } .right { text-align: right; } .stack > * + * { margin-top: .75rem; } .mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; } .row { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; } .row--between { justify-content: space-between; } .hidden { display: none !important; } /* Spacing utilities. These exist so the templates carry no inline `style=` attributes, which a strict Content-Security-Policy (`style-src 'self'`) would block. */ .mb-lg { margin-bottom: 1.25rem; } .mt-lg { margin-top: 2rem; } .empty { padding: 2.5rem 1rem; text-align: center; color: var(--text-faint); } .empty__icon { font-size: 2rem; display: block; margin-bottom: .5rem; opacity: .7; } /* --------------------------------------------------------------- reading */ .reading-list { list-style: none; margin: 0; padding: 0; } .reading-list__item { display: flex; gap: .75rem; align-items: flex-start; padding: .6rem 0; border-bottom: 1px solid var(--border); } .reading-list__item:last-child { border-bottom: none; } .reading-list__date { font-family: var(--mono); font-size: .82rem; color: var(--text-muted); flex: 0 0 5.5rem; } .reading-list__sg { font-family: var(--mono); font-weight: 650; flex: 0 0 4rem; } .reading-list__body { flex: 1; min-width: 0; } .reading-list__comment { color: var(--text-muted); font-size: .84rem; } /* ------------------------------------------------------------- advice */ /* The LLM's advice. It sits next to the brewer's own comment, never replaces it, and is visually distinct so the two are never confused. */ .advice { display: block; margin-top: .35rem; padding: .5rem .65rem; border-left: 2px solid var(--amber); border-radius: 0 4px 4px 0; background: var(--amber-dim); color: var(--text); font-size: .8125rem; line-height: 1.5; } .advice__label { display: block; margin-bottom: .15rem; font-size: .625rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--amber-text); } /* The advice on the active-beers card and the run detail page - the full text, not the clamped table cell. */ .advice--reading { margin-top: .5rem; } /* Advice that could not be generated - it says why. */ .advice--failed { border-left-color: var(--danger); background: var(--danger-dim); color: var(--text-muted); } .advice--failed .advice__label { color: var(--danger); } /* The advice in the table is a compact trigger that pops the full text out on hover, focus or tap. It used to be the text itself, clamped to four lines. The advice runs to several hundred characters, and a cell that wide pushes the table past the width of a phone, so the column ended up clipped off the right edge and unreadable without sideways scrolling. */ .advice-cell { position: relative; width: 1%; white-space: nowrap; } .advice-trigger { display: inline-flex; align-items: center; gap: .35rem; padding: .25rem .55rem; border: 1px solid var(--amber); border-radius: 999px; background: var(--amber-dim); color: var(--amber-text); font: inherit; font-size: .75rem; line-height: 1.4; cursor: pointer; white-space: nowrap; } .advice-trigger:hover, .advice-trigger:focus-visible { background: var(--amber); color: var(--bg); } .advice-trigger--failed { border-color: var(--danger); background: var(--danger-dim); color: var(--danger); } .advice-trigger__icon { font-size: .85em; } /* The pop-out. It is `position: fixed` and anchored to the trigger by the script, not absolutely positioned inside the cell. The table is a scroll container, and an absolutely positioned panel inside it was clipped by the container's own overflow - the advice was sliced in half by the card's edge and the bottom border was cut off. Fixed positioning takes it out of the table entirely, so it floats above the page and is never cut by a scroll container. */ .advice-pop { position: fixed; z-index: 200; display: none; width: min(30rem, 92vw); max-height: 70vh; overflow-y: auto; padding: .8rem .9rem; border: 1px solid var(--amber); border-radius: 8px; background: var(--bg-raised); box-shadow: 0 12px 32px rgba(0, 0, 0, .55); text-align: left; white-space: normal; } .advice-pop__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .4rem; } .advice-pop__head .advice__label { margin-bottom: 0; } .advice-pop__close { border: 0; background: none; color: var(--text-muted); font-size: 1.1rem; line-height: 1; cursor: pointer; padding: 0 .15rem; } .advice-pop__close:hover { color: var(--text); } .advice-pop__text { margin: 0; font-size: .8125rem; line-height: 1.55; color: var(--text); } /* The script opens and closes the panel, and places it. The CSS only decides whether it is shown. */ .advice-pop.is-open { display: block; } /* On a phone there is no hover, so the trigger is a button the script toggles, and the panel is pinned to the middle of the screen so it is readable whatever the table's width. */ @media (max-width: 720px) { .advice-cell { width: auto; } /* On a phone the panel is centred on the screen rather than anchored to the trigger - there is not the room to float it beside the cell, and the trigger may be near the edge. */ .advice-pop { top: 50% !important; left: 50% !important; transform: translate(-50%, -50%); } }