/* The colours are the website's, as its blog pages use them (website/tailwind.config.js, website/src/css/blog.css and website/src/_includes/layouts/article.html): the page's ground, the article's card, the heading gradient, and the link and button colours, in both themes. Every other value below is the published SimpleX design's own; where one is not, the line says why. */ :root { /* Tell the UA which ground to paint before the first message and on a reload's blank frame, and which form controls and scrollbars to render; the dark blocks flip it with the palette. */ color-scheme: light; /* primary-light and its hover step; white on it, as on the site's buttons. Pressed is the accent one small step darker rather than the site's lighter, greyer #407AD2: a press should read as the same button under the finger, not a paler one. */ --accent: #0053D0; --accent-hover: #1661D1; --accent-pressed: #004ABB; --on-accent: #FFFFFF; --ink: #0D1B3A; /* simplex.domains' ink: the navy the page's blues are built on */ --bg: #F3FAFF; /* secondary-bg-light: the blog page's ground */ --surface: #FFFFFF; /* the article's card */ --menu: #FFFFFF; --line: rgba(0, 83, 208, .14); /* simplex.domains' card line: the accent, faint, so it sits in the page's blue */ /* one faint wash of the accent over the flat ground, and nothing else */ --page: radial-gradient(50% 50% at 50% 50%, rgba(0, 83, 208, .06) 0%, rgba(243, 250, 255, 0) 100%); /* The one secondary text colour, simplex.domains' own: the ink at 65%, so it stays in the page's hue. 5.3:1 on #F3FAFF, and set at 500 wherever it is used. */ --ink-soft: rgba(13, 27, 58, .651); /* The ink at 4%: the menu's hover, the landing screen's info panel, and a card the catalog cannot price. */ --tint: rgba(13, 27, 58, .04); /* the blog's heading gradient, top to bottom */ --title: linear-gradient(to bottom, #53C1FF -50%, #0053D0 160%); /* Settled, waiting and failed, each a foreground on its own ground. */ --ok-fg: #1c7c3f; --ok-bg: #e8f5ec; --ok-line: #bfe3cc; --warn-fg: #8a6100; --warn-bg: #fff8e6; --warn-line: #f0dcae; --danger-fg: #b3261e; --danger-bg: #fdecec; --danger-line: #f3c9c6; /* the code screen's code frame, in the accent */ --code-bg: rgba(0, 83, 208, .06); --code-line: rgba(0, 83, 208, .35); /* A primary button with nothing to do: a flat bar with a washed label, legible at 4.0:1. See `.primary[disabled]` for why it is not the accent faded. */ --disabled: rgba(13, 27, 58, .07); --on-disabled: rgba(13, 27, 58, .50); /* Switched with the theme rather than tinted by it. The dark wordmark is the same file with its `#030749` set to white. */ --hero: url(hero-light.png); --wordmark: url(wordmark-light.svg); /* a card is a 1px border at radius 20 with no shadow, and every button a pill; the shadows on the page are the menu's and the primary button's */ --r-card: 20px; --r-pill: 9999px; --shadow-pop: 0 2px 6px rgba(0, 0, 0, .06), 0 16px 40px rgba(0, 0, 0, .12); /* the primary button: a touch of light across its top and a soft shadow in the accent */ --sheen: linear-gradient(to bottom, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 60%); --shadow-button: 0 4px 12px rgba(0, 83, 208, .18); --shadow-button-hover: 0 6px 16px rgba(0, 83, 208, .24); /* The faces simplex.domains sets: GT Walsheim for the heading, Manrope for everything else. Both are served under the build hash (see the @font-face rules below) and precached. */ --display: "GT Walsheim", Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; --font: Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } /* The four Manrope weights the sheet uses and the one GT Walsheim weight, relative to this file, so they sit under the build hash with it. `swap`, so text is never invisible while a face loads. */ @font-face { font-family: Manrope; src: url(Manrope-Regular.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: Manrope; src: url(Manrope-Medium.woff2) format("woff2"); font-weight: 500; font-style: normal; font-display: swap; } @font-face { font-family: Manrope; src: url(Manrope-SemiBold.woff2) format("woff2"); font-weight: 600; font-style: normal; font-display: swap; } @font-face { font-family: Manrope; src: url(Manrope-Bold.woff2) format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } @font-face { font-family: "GT Walsheim"; src: url(GT-Walsheim-LC-Bold.woff2) format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } /* The dark palette is written twice on purpose: the media query claims everything that is not an explicit light, and the attribute rule claims an explicit dark, which is how `system`, `light` and `dark` all win where they should. Both blocks must declare the same tokens and values, and `design.test.ts` fails if they diverge. */ @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; /* primary-dark, with its hover and pressed steps, and the page's ground on it, as on the site's dark buttons */ --accent: #70F0F9; --accent-hover: #66D9E2; --accent-pressed: #5CD3DC; --on-accent: #000832; --ink: #EAF2FF; /* simplex.domains' dark ink */ --bg: #000832; /* primary-bg-dark: the blog page's ground */ --surface: #0B2A59; /* secondary-bg-dark: the blog list's card, a clear step off the ground */ --menu: #0B2A59; --line: rgba(112, 240, 249, .18); /* simplex.domains' dark card line: the accent, faint */ --page: radial-gradient(50% 50% at 50% 50%, rgba(112, 240, 249, .05) 0%, rgba(0, 8, 50, 0) 100%); --ink-soft: rgba(234, 242, 255, .735); --tint: rgba(255, 255, 255, .06); --title: linear-gradient(to bottom, #70F0F9 0%, #70F0F9 33%, #50D8F1 100%); /* The light theme's three hues, lightened to sit on #000832, each with its own ground at a low alpha of itself. */ --ok-fg: #7FE3A6; --ok-bg: rgba(127, 227, 166, .12); --ok-line: rgba(127, 227, 166, .28); --warn-fg: #F5C86A; --warn-bg: rgba(245, 200, 106, .12); --warn-line: rgba(245, 200, 106, .28); --danger-fg: #FF9F98; --danger-bg: rgba(255, 159, 152, .12); --danger-line: rgba(255, 159, 152, .28); --code-bg: rgba(112, 240, 249, .12); --code-line: rgba(112, 240, 249, .45); --disabled: rgba(255, 255, 255, .09); --on-disabled: rgba(255, 255, 255, .45); --hero: url(hero-dark.png); --wordmark: url(wordmark-dark.svg); --shadow-pop: 0 2px 8px rgba(0, 0, 0, .50), 0 16px 40px rgba(0, 0, 0, .55); /* White barely shows on the light cyan, so the dark sheen also deepens the pill's foot. */ --sheen: linear-gradient(to bottom, rgba(255, 255, 255, .30), rgba(255, 255, 255, 0) 50%, rgba(0, 8, 50, .16) 100%); --shadow-button: 0 6px 16px rgba(112, 240, 249, .16); --shadow-button-hover: 0 8px 20px rgba(112, 240, 249, .22); } } /* The same palette again, for the menu's explicit Dark. */ :root[data-theme="dark"] { color-scheme: dark; /* primary-dark, with its hover and pressed steps, and the page's ground on it, as on the site's dark buttons */ --accent: #70F0F9; --accent-hover: #66D9E2; --accent-pressed: #5CD3DC; --on-accent: #000832; --ink: #EAF2FF; /* simplex.domains' dark ink */ --bg: #000832; /* primary-bg-dark: the blog page's ground */ --surface: #0B2A59; /* secondary-bg-dark: the blog list's card, a clear step off the ground */ --menu: #0B2A59; --line: rgba(112, 240, 249, .18); /* simplex.domains' dark card line: the accent, faint */ --page: radial-gradient(50% 50% at 50% 50%, rgba(112, 240, 249, .05) 0%, rgba(0, 8, 50, 0) 100%); --ink-soft: rgba(234, 242, 255, .735); --tint: rgba(255, 255, 255, .06); --title: linear-gradient(to bottom, #70F0F9 0%, #70F0F9 33%, #50D8F1 100%); /* The light theme's three hues, lightened to sit on #000832, each with its own ground at a low alpha of itself. */ --ok-fg: #7FE3A6; --ok-bg: rgba(127, 227, 166, .12); --ok-line: rgba(127, 227, 166, .28); --warn-fg: #F5C86A; --warn-bg: rgba(245, 200, 106, .12); --warn-line: rgba(245, 200, 106, .28); --danger-fg: #FF9F98; --danger-bg: rgba(255, 159, 152, .12); --danger-line: rgba(255, 159, 152, .28); --code-bg: rgba(112, 240, 249, .12); --code-line: rgba(112, 240, 249, .45); --disabled: rgba(255, 255, 255, .09); --on-disabled: rgba(255, 255, 255, .45); --hero: url(hero-dark.png); --wordmark: url(wordmark-dark.svg); --shadow-pop: 0 2px 8px rgba(0, 0, 0, .50), 0 16px 40px rgba(0, 0, 0, .55); /* White barely shows on the light cyan, so the dark sheen also deepens the pill's foot. */ --sheen: linear-gradient(to bottom, rgba(255, 255, 255, .30), rgba(255, 255, 255, 0) 50%, rgba(0, 8, 50, .16) 100%); --shadow-button: 0 6px 16px rgba(112, 240, 249, .16); --shadow-button-hover: 0 8px 20px rgba(112, 240, 249, .22); } * { box-sizing: border-box; } /* Reserve the scrollbar's width always, so a panel whose height changes (the Payment Element autofilling or a 3DS challenge resizing it) cannot toggle the scrollbar and jog the centred column sideways, which `#app`'s overflow-x then clips. */ html { scrollbar-gutter: stable; } /* The page is one column of the viewport's height: the header, then the screen, which is at least the rest of the viewport tall (see `.panel`), then the footer below the fold, where a scroll reaches it. `100vh` is the fallback for a browser without dynamic viewport units. */ body { margin: 0; display: flex; flex-direction: column; /* The gutter is here, so `#app` is exactly the 640px content column and nothing inside it has to subtract padding to reach that width. */ padding: 0 20px; min-height: 100vh; min-height: 100dvh; background: var(--bg); /* Fixed, so the wash does not tile or scroll away on a long screen. */ background-image: var(--page); background-attachment: fixed; color: var(--ink); font-family: var(--font); /* the scale: 1rem/1.25 body, .875 small, .75 extra-small, larger steps below */ font-size: 16px; line-height: 1.5; -webkit-font-smoothing: antialiased; } #app { width: 100%; max-width: 640px; margin: 0 auto; overflow-x: hidden; flex: 1 0 auto; } /* The header's height, which every screen's minimum height is the viewport less: `.chrome-bar`'s 56px box, its paddings inside it. */ :root { --chrome-h: 56px; } /* The shell ships a static copy of the first screen (see index.html), so the first paint is the real landing, not an empty page, and `main.ts` swaps in its own identical markup with no flash. Embedded, the site owns the navbar, so the shell's copy of it is hidden there as the built one would be. */ .embedded #chrome { display: none; } /* A reload of any screen but the landing can't be prerendered (the screen depends on runtime state), so `init.js` marks it `sb-booting` before the first paint: the shell's landing is held hidden over the themed ground, and `main.ts` clears the mark once it has painted the real screen, which then fades in rather than replacing a flash of the landing. The landing route is never marked, so its prerendered first paint stays instant. */ #app { transition: opacity .2s ease; } .sb-booting #app { opacity: 0; } /* Embedded in the site: the site's fixed navbar sits above the frame, so pad the top to clear it, and drop the page's own wash so the flat background the site hands in shows through cleanly. The site carries its own footer below the frame, so ours would only double the contact link and leave its accent line at the frame's edge — hide it embedded. */ /* Standalone, the body fills the viewport so the footer sits at the bottom; embedded, the host sizes the frame to the body, so a `100vh` floor would make the body's height depend on the frame height the host derived from it — a loop that ratchets the frame taller and drops the site's footer as the zoom shifts. Drop the floor so the body is exactly its content. */ .embedded body { padding-top: 54px; background-image: none; min-height: 0; display: block; } .embedded .panel { min-height: 0; } .embedded footer { display: none; } /* Embedded in the site's dark theme, the standalone grey surfaces read as off against the navy the site hands in. Follow the site's own dark-card idiom instead: a faint white veil and hairline on the navy ground, so a panel is a lighter navy rather than a grey block. Both selectors, to match `system` dark (media query) and the explicit Dark choice (data-theme). */ @media (prefers-color-scheme: dark) { :root.embedded:not([data-theme="light"]) { --surface: rgba(255, 255, 255, .05); --menu: rgba(255, 255, 255, .07); --line: rgba(255, 255, 255, .22); } } :root.embedded[data-theme="dark"] { --surface: rgba(255, 255, 255, .05); --menu: rgba(255, 255, 255, .07); --line: rgba(255, 255, 255, .22); } /* ------------------------------------------------------------------- chrome */ /* The wordmark on the left, and on the right a circular icon button holding the hamburger. It spans the page rather than the 640 column, so the column reads as content inside a site rather than as the whole site. */ .chrome-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 56px; max-width: 1120px; margin: 0 auto; padding: 8px 4px; } /* The official wordmark, drawn from the file. The URL is relative, so it resolves inside /assets// beside this sheet and is precached with everything else. */ .brand { display: block; width: 132px; aspect-ratio: 161 / 40; background-image: var(--wordmark); background-size: contain; background-position: left center; background-repeat: no-repeat; /* A link with no text: the accessible name is on the element. */ text-indent: -9999px; overflow: hidden; } .menu-wrap { position: relative; } /* 40 rather than the reference's 32, which is under every platform's minimum touch target and this is the header's only control. */ .menu-button { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; /* The hairline colour as a fill, which on both grounds is the reference's own circle without a fourth grey. */ background: var(--line); color: var(--ink); cursor: pointer; } .menu-button:hover, .menu-button[aria-expanded="true"] { color: var(--accent); } .bars { display: block; width: 20px; height: 20px; } /* The panel, anchored under the button and right-aligned to it, one step off the page ground, with a hairline and the page's only drop shadow. */ .menu { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: 320px; border: 1px solid var(--line); border-radius: 14px; background: var(--menu); box-shadow: var(--shadow-pop); text-align: left; overflow: hidden; } .menu[hidden] { display: none; } /* Full-bleed hairlines between sections, so the padding is on the section and never on the panel. */ .menu-section { padding: 6px; } .menu-section + .menu-section { border-top: 1px solid var(--line); } .menu-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 10px; } .menu-label { font-size: .875rem; font-weight: 700; color: var(--ink); } /* the segmented setting: three values in one pill, the chosen one in the accent with white on it. */ .segmented { display: flex; padding: 2px; border-radius: var(--r-pill); background: var(--tint); } .segment { padding: 5px 11px; border: 0; border-radius: var(--r-pill); background: none; color: var(--ink-soft); font: inherit; font-size: .875rem; font-weight: 700; cursor: pointer; } .segment:hover { color: var(--ink); } .segment[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); } .menu-item { display: block; width: 100%; padding: 10px; border: 0; border-radius: 10px; background: none; color: var(--ink); font: inherit; font-size: .875rem; font-weight: 500; text-align: left; cursor: pointer; } .menu-item[hidden] { display: none; } .menu-item:hover { background: var(--tint); color: var(--accent); } .menu-item.danger { color: var(--danger-fg); } .menu-item.danger:hover { background: var(--danger-bg); color: var(--danger-fg); } /* the footer, on every screen: a hairline across the column, then the contact link centred under it in the accent. */ footer { flex: none; width: 100%; max-width: 640px; margin: 0 auto; text-align: center; } footer a { display: block; border-top: 1px solid var(--line); padding: 22px 0 34px; color: var(--accent); font-size: .875rem; text-decoration: none; } footer a:hover { text-decoration: underline; } /* The keyboard's equivalent of the hover underline, declared rather than left to the user agent, whose thin dark outline all but disappears on the accent button and on the dark ground. `:focus-visible`, so a mouse press leaves nothing behind. */ :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } /* On the accent ground itself an accent ring is invisible, so it inverts. */ .primary:not(.outline):focus-visible { outline-color: var(--ink); } /* -------------------------------------------------------------- the wizard */ /* the horizontal track, in two elements, because one cannot clip and travel at the same time. `.track` clips and is the height of the panel in view; `.rail` is the flex row of four panels and is what translates. Both animate, so the outgoing panel travels off one edge while the incoming one arrives at the other. `main.ts` writes the height and the transform, and sets `--slide` to 0ms for any move that is not a step. `overflow: hidden` is also what makes this a stepper rather than a carousel: there is no scroll to drag. Unreached panels carry `inert`, so Tab cannot enter them either. */ .track { overflow: hidden; transition: height var(--slide, 320ms) cubic-bezier(.22, .61, .36, 1); } .rail { display: flex; align-items: flex-start; width: 100%; transition: transform var(--slide, 320ms) cubic-bezier(.22, .61, .36, 1); } /* Below the column width each panel is the viewport width: the same track is the phone flow, with only the padding and the type scale changing. */ .panel { position: relative; flex: 0 0 100%; min-width: 0; padding: 12px 0 22px; text-align: center; /* A screen is a column at least as tall as the viewport under the header, so that its button stands at the same place on every screen - near the bottom, where a thumb reaches it - and the content between the heading and the button is spread over the height rather than stacked at the top. A screen taller than the viewport grows and scrolls, as the payment screens do. */ display: flex; flex-direction: column; min-height: calc(100vh - var(--chrome-h)); min-height: calc(100dvh - var(--chrome-h)); } /* On a wide screen the button needs no thumb, so it stands higher off the foot of the viewport and the page reads as balanced rather than bottom-heavy. Up to a 1080px-tall viewport the space under it grows with the height; beyond that the content stops descending - its foot stays 927px under the header, where a 1080px viewport puts it - and the whole surplus goes under it. */ @media (min-width: 700px) { .panel { padding-bottom: max(clamp(40px, 9vh, 110px), calc(100vh - var(--chrome-h) - 927px)); padding-bottom: max(clamp(40px, 9vh, 110px), calc(100dvh - var(--chrome-h) - 927px)); } } /* What each screen spreads: the hero, the choice cards, the summary. `auto` above and nothing below, so the free height is shared between the space over the block and the space under it, which the button's own `auto` margin takes. */ .panel > .hero, .panel > .choices, .panel > .rows { margin-top: auto; } /* The button is the last thing before the invest block, and sinks to the foot of the screen. Where a screen keeps notes above its button, the notes sink with it and the button follows them. */ .panel > .primary { margin-top: auto; } .panel > .notes { margin-top: auto; } .notes + .primary { margin-top: 20px; } .notes .muted { margin: 4px auto 0; max-width: 480px; } /* The checkout's note slot holds one line's height whether or not the line is shown, so choosing a method moves nothing above or below it. */ .notes.slot { min-height: calc(4px + .875rem * 1.5); } .notes .half { display: inline-block; } @media (prefers-reduced-motion: reduce) { .track, .rail { transition: none; } } /* Every payment screen and `#/codes` takes the same shell as a wizard panel. The 20px a trailing button adds is the difference between a footer rule under a button and one under a block of text. */ .panel > button:last-child { margin-bottom: 20px; } /* ------------------------------------------------------------------ headings */ h1 { font-family: var(--display); font-size: 2.25rem; line-height: 3rem; font-weight: 700; letter-spacing: -.02em; color: var(--ink); margin: 12px 0 0; } /* The heading is the gradient, clipped to its own glyphs, in both themes. Guarded, because the fill is transparent: a browser that cannot clip a background to text would render every heading invisible. */ @supports ((background-clip: text) or (-webkit-background-clip: text)) { h1 { background-image: var(--title); -webkit-background-clip: text; background-clip: text; color: transparent; } } /* the payment screen and the code screen take one step down from the landing screen's. */ h1.tight { font-size: 1.875rem; line-height: 2.5rem; margin-top: 15px; } .lede { font-size: 1.125rem; line-height: 1.5; font-weight: 500; color: var(--ink-soft); margin: 10px 0 0; } h1 + .lede { margin-top: 10px; } h1.tight + .lede { margin-top: 6px; } /* Two ledes are two sentences of one paragraph, a line height apart rather than a paragraph gap. */ .lede + .lede { margin-top: 0; } .lede .line { display: block; } .lede .half { display: inline-block; } .muted { color: var(--ink-soft); font-size: .875rem; font-weight: 500; margin: 14px 0 0; } /* A narrower measure than the column, so the closing footnote breaks in two rather than reading as a caption that ran on. Scoped to a direct child, so it cannot reach the same class inside a left-aligned field and indent the line it holds. */ .panel > p.muted { max-width: 332px; margin-left: auto; margin-right: auto; } /* Shown beside the status while the browser is offline, not instead of it. */ .offline { color: var(--warn-fg); } .center { text-align: center; } /* Figures that are compared down a column, or that change in place while the buyer is looking at them. The default proportional digits are narrower on 1 than on 0, so the payment screen's held-rate clock and the rate-limited screen's countdown shifted every second they ticked, and the duration list's three prices did not line up under one another. `.notice .title` is the rate-limited screen's countdown, which is the only figure that line ever holds. */ .row, .choice .price, .rate, .notice .title, .entry .meta { font-variant-numeric: tabular-nums; } /* Back is out of the flow, so the heading is the first thing in every panel and stands at one height whether or not there is a Back. On a desktop `top` centres it on the heading's first line, at the left of the column, as a navigation bar draws it. On a phone the heading is nearly as wide as the column, so Back is above it and the heading's margin holds that line open on every screen. The chevron hangs a little into the gutter so the word aligns with the column's edge. */ .back { position: absolute; left: -5px; top: 36px; display: flex; align-items: center; gap: 1px; color: var(--accent); background: none; border: 0; font: inherit; font-size: 1rem; font-weight: 500; text-align: left; cursor: pointer; padding: 0; } .back .chevron { width: 22px; height: 22px; display: block; } /* -------------------------------------------------------------------- buttons */ /* Spans the column because it is the column's one action. */ .primary { display: block; width: 100%; min-height: 48px; padding: 8px 16px; border: 0; border-radius: var(--r-pill); background: var(--accent); background-image: var(--sheen); box-shadow: var(--shadow-button); color: var(--on-accent); font: inherit; font-size: 1rem; font-weight: 700; line-height: 1.25; cursor: pointer; margin: 24px 0 0; transition: background-color 120ms linear, box-shadow 120ms linear; } .primary:not([disabled]):not(.copied):hover { background-color: var(--accent-hover); box-shadow: var(--shadow-button-hover); } .primary:not([disabled]):not(.copied):active { background-color: var(--accent-pressed); box-shadow: none; } /* A different shape, not a faded one: the accent at reduced opacity still reads as the live button, so a Continue that cannot continue looks broken rather than not-yet-answered. */ .primary[disabled] { background: var(--disabled); box-shadow: none; color: var(--on-disabled); cursor: default; } /* The same button as an outline, which is what the closed-window screen's [ New invoice ] and the code screen's [ Copy code ] are. */ .primary.outline { background: none; box-shadow: none; color: var(--accent); border: 1.5px solid var(--accent); } .primary.outline:not([disabled]):not(.copied):hover { background: var(--tint); color: var(--accent-hover); } /* A minimum height and not a fixed one: at the 320px floor a two-line label would otherwise put its second line outside the border. */ .secondary { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 48px; padding: 8px 16px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface); color: var(--accent); font: inherit; font-size: 1rem; font-weight: 700; text-align: center; text-decoration: none; cursor: pointer; margin: 12px 0 0; line-height: 1.25; } .secondary:not(.copied):hover { border-color: var(--accent); } /* the payment screen's Copy, which lives inside the address panel rather than under it. */ .secondary.inline { display: inline; width: auto; min-height: 0; height: auto; padding: 0; border: 0; background: none; font-size: .875rem; line-height: inherit; margin: 0; } .secondary.inline:not(.copied):hover { text-decoration: underline; } /* A copy that landed, confirmed on the control itself for two seconds. Every hover rule above excludes it: the pointer is still on the button that was just pressed, and a hover colour would overwrite the confirmation. */ .copied { color: var(--ok-fg); border-color: var(--ok-line); } .primary.copied { background: none; box-shadow: none; color: var(--ok-fg); border-color: var(--ok-fg); } .secondary.inline.copied { text-decoration: none; } /* The failure line only: a success never lands here, so this is empty until something goes wrong, and empty it takes up no room. */ .copy-status:empty, .cancel-status:empty { display: none; } .link { background: none; border: 0; padding: 0; font: inherit; font-size: .875rem; color: var(--accent); cursor: pointer; text-decoration: none; } .link:hover { text-decoration: underline; } .link.danger { color: var(--danger-fg); } .link[disabled] { color: var(--ink-soft); cursor: default; text-decoration: none; } p.row-line { margin: 16px 0 0; } /* --------------------------------------------------------------- the choices */ /* the tier list's tiers and the duration list's durations stay side by side at every width: values being compared must stay comparable. Only the type scale shrinks. */ .choices { display: flex; gap: 14px; margin: 26px 0 0; align-items: stretch; } .choice { /* A column, explicitly top-aligned: a