Render bracket references as superscript text

This commit improves markdown rendering to convert reference labels
(e.g., `[1]`) to superscripts, improving document readability without
cluttering the text. This improvement applies documentation of all
scripts and categories.

Changes:

- Implement superscript conversion for reference labels within markdown
  content, ensuring a cleaner presentation of textual references.
- Enable HTML content within markdown, necessary for inserting `<sup>`
  elements due to limitations in `markdown-it`, see
  markdown-it/markdown-it#999 for details.
- Refactor markdown rendering process for improved testability and
  adherence to the Single Responsibility Principle.
- Create `_typography.scss` with font size definitions, facilitating
  better control over text presentation.
- Adjust external URL indicator icon sizing for consistency, aligning
  images with the top of the text to maintain a uniform appearence.
- Use normal font-size explicitly for documentation text to ensure
  consistency.
- Remove text size specification in `markdown-styles` mixin, using `1em`
  for spacing to simplify styling.
- Rename font sizing variables for clarity, distinguishing between
  absolute and relative units.
- Change `font-size-relative-smaller` to be `80%`, browser default for
  `font-size: smaller;` CSS style and use it with `<sup>` elements.
- Improve the logic for converting plain URLs to hyperlinks, removing
  trailing whitespace for cleaner link generation.
- Fix plain URL to hyperlink (autolinking) logic removing trailing
  whitespace from the original markdown content. This was revealed by
  tests after separating its logic.
- Increase test coverage with more tests.
- Add types for `markdown-it` through `@types/markdown-it` package for
  better editor support and maintainability.
- Simplify implementation of adding custom anchor attributes in
  `markdown-it` using latest documentation.
This commit is contained in:
undergroundwires
2024-02-09 16:25:05 +01:00
parent 311fcb1813
commit b9c89b701f
42 changed files with 1036 additions and 378 deletions

View File

@@ -81,7 +81,7 @@ export default defineComponent({
border-radius: 4px;
.button__icon {
font-size: $font-size-larger;
font-size: $font-size-absolute-x-large;
}
@include clickable;
@@ -99,7 +99,7 @@ export default defineComponent({
.button__text {
display: none;
font-family: $font-artistic;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
color: $color-primary;
font-weight: 500;
@include hover-or-touch {

View File

@@ -63,14 +63,14 @@ export default defineComponent({
padding: 0.2rem;
.dollar {
margin-right: 0.5rem;
font-size: $font-size-smaller;
font-size: $font-size-absolute-x-small;
user-select: none;
}
.copy-action-container {
margin-left: 1rem;
}
code {
font-size: $font-size-small;
font-size: $font-size-absolute-small;
}
}
</style>

View File

@@ -203,7 +203,7 @@ function getDefaultCode(language: ScriptingLanguage): string {
width: 100%;
height: 100%;
overflow: auto;
font-size: $font-size-small;
font-size: $font-size-absolute-small;
&__highlight {
background-color: $color-secondary-light;
position: absolute;

View File

@@ -142,7 +142,7 @@ function isClickable(element: Element) {
.error {
width: 100%;
text-align: center;
font-size: $font-size-largest;
font-size: $font-size-absolute-xx-large;
font-family: $font-normal;
}

View File

@@ -168,7 +168,7 @@ $card-horizontal-gap : $card-gap;
flex-direction: column;
flex: 1;
justify-content: center;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
}
.card__inner__selection_indicator {
height: $card-inner-padding;
@@ -181,7 +181,7 @@ $card-horizontal-gap : $card-gap;
width: 100%;
margin-top: .25em;
vertical-align: middle;
font-size: $font-size-normal;
font-size: $font-size-absolute-normal;
}
}
.card__expander {
@@ -203,7 +203,7 @@ $card-horizontal-gap : $card-gap;
}
.card__expander__close-button {
font-size: $font-size-large;
font-size: $font-size-absolute-large;
align-self: flex-end;
margin-right: 0.25em;
@include clickable;

View File

@@ -57,6 +57,6 @@ export default defineComponent({
<style scoped lang="scss">
@use "@/presentation/assets/styles/main" as *;
.icon {
font-size: $font-size-normal;
font-size: $font-size-absolute-normal;
}
</style>

View File

@@ -151,7 +151,7 @@ $margin-inner: 4px;
margin-top: 1em;
color: $color-primary-light;
.search__query__close-button {
font-size: $font-size-large;
font-size: $font-size-absolute-large;
margin-left: 0.25rem;
}
}
@@ -160,7 +160,7 @@ $margin-inner: 4px;
flex-direction: column;
word-break:break-word;
color: $color-on-primary;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
padding:10px;
text-align:center;
> div {

View File

@@ -59,7 +59,7 @@ function formatAsMarkdownListItem(content: string): string {
flex: 1; // Expands the container to fill available horizontal space, enabling alignment of child items.
max-width: 100%; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
font-size: $font-size-normal;
font-size: $font-size-absolute-normal;
font-family: $font-main;
}
</style>

View File

@@ -49,7 +49,7 @@ export default defineComponent({
.documentation-button {
vertical-align: middle;
color: $color-primary;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
:deep() { // This override leads to inconsistent highlight color, it should be re-styled.
@include hover-or-touch {
color: $color-primary-darker;

View File

@@ -0,0 +1,28 @@
import { InlineReferenceLabelsToSuperscriptConverter } from './Renderers/InlineReferenceLabelsToSuperscriptConverter';
import { MarkdownItHtmlRenderer } from './Renderers/MarkdownItHtmlRenderer';
import { PlainTextUrlsToHyperlinksConverter } from './Renderers/PlainTextUrlsToHyperlinksConverter';
import type { MarkdownRenderer } from './MarkdownRenderer';
export class CompositeMarkdownRenderer implements MarkdownRenderer {
constructor(
private readonly renderers: readonly MarkdownRenderer[] = StandardMarkdownRenderers,
) {
if (!renderers.length) {
throw new Error('missing renderers');
}
}
public render(markdownContent: string): string {
let renderedContent = markdownContent;
for (const renderer of this.renderers) {
renderedContent = renderer.render(renderedContent);
}
return renderedContent;
}
}
const StandardMarkdownRenderers: readonly MarkdownRenderer[] = [
new PlainTextUrlsToHyperlinksConverter(),
new InlineReferenceLabelsToSuperscriptConverter(),
new MarkdownItHtmlRenderer(),
] as const;

View File

@@ -1,196 +1,3 @@
import MarkdownIt from 'markdown-it';
import Renderer from 'markdown-it/lib/renderer';
import Token from 'markdown-it/lib/token';
export function createMarkdownRenderer(): MarkdownRenderer {
const markdownParser = new MarkdownIt({
linkify: false, // Disables auto-linking; handled manually for custom formatting.
breaks: false, // Disables conversion of single newlines (`\n`) to HTML breaks (`<br>`).
});
configureLinksToOpenInNewTab(markdownParser);
return {
render: (markdownContent: string) => {
markdownContent = beautifyAutoLinkedUrls(markdownContent);
return markdownParser.render(markdownContent);
},
};
}
interface MarkdownRenderer {
export interface MarkdownRenderer {
render(markdownContent: string): string;
}
const PlainTextUrlInMarkdownRegex = /(?<!\]\(|\[\d+\]:\s+|https?\S+|`)((?:https?):\/\/[^\s\])]*)(?:[\])](?!\()|$|\s)/gm;
function beautifyAutoLinkedUrls(content: string): string {
if (!content) {
return content;
}
return content.replaceAll(PlainTextUrlInMarkdownRegex, (_fullMatch, url) => {
return formatReadableLink(url);
});
}
function formatReadableLink(url: string): string {
const urlParts = new URL(url);
let displayText = formatHostName(urlParts.hostname);
const pageLabel = extractPageLabel(urlParts);
if (pageLabel) {
displayText += ` - ${truncateTextFromEnd(capitalizeEachWord(pageLabel), 50)}`;
}
if (displayText.includes('Msdn.microsoft')) {
console.log(`[${displayText}](${urlParts.href})`);
}
return buildMarkdownLink(displayText, urlParts.href);
}
function formatHostName(hostname: string): string {
const withoutWww = hostname.replace(/^(www\.)/, '');
const truncatedHostName = truncateTextFromStart(withoutWww, 30);
return truncatedHostName;
}
function extractPageLabel(urlParts: URL): string | undefined {
const readablePath = makePathReadable(urlParts.pathname);
if (readablePath) {
return readablePath;
}
return formatQueryParameters(urlParts.searchParams);
}
function buildMarkdownLink(label: string, url: string): string {
return `[${label}](${url})`;
}
function formatQueryParameters(queryParameters: URLSearchParams): string | undefined {
const queryValues = [...queryParameters.values()];
if (queryValues.length === 0) {
return undefined;
}
return findMostDescriptiveName(queryValues);
}
function truncateTextFromStart(text: string, maxLength: number): string {
return text.length > maxLength ? `${text.substring(text.length - maxLength)}` : text;
}
function truncateTextFromEnd(text: string, maxLength: number): string {
return text.length > maxLength ? `${text.substring(0, maxLength)}` : text;
}
function isNumeric(value: string): boolean {
return /^\d+$/.test(value);
}
function makePathReadable(path: string): string | undefined {
const decodedPath = decodeURI(path); // Decode URI components, e.g., '%20' to space
const pathParts = decodedPath.split('/');
const decodedPathParts = pathParts // Split then decode to correctly handle '%2F' as '/'
.map((pathPart) => decodeURIComponent(pathPart));
const descriptivePart = findMostDescriptiveName(decodedPathParts);
if (!descriptivePart) {
return undefined;
}
const withoutExtension = removeFileExtension(descriptivePart);
const tokenizedText = tokenizeTextForReadability(withoutExtension);
return tokenizedText;
}
function tokenizeTextForReadability(text: string): string {
return text
.replaceAll(/[-_+]/g, ' ') // Replace hyphens, underscores, and plus signs with spaces
.replaceAll(/\s+/g, ' '); // Collapse multiple consecutive spaces into a single space
}
function removeFileExtension(value: string): string {
const parts = value.split('.');
if (parts.length === 1) {
return value;
}
const extension = parts[parts.length - 1];
if (extension.length > 9) {
return value; // Heuristically web file extension is no longer than 9 chars (e.g. "html")
}
return parts.slice(0, -1).join('.');
}
function capitalizeEachWord(text: string): string {
return text
.split(' ')
.map((word) => capitalizeFirstLetter(word))
.join(' ');
}
function capitalizeFirstLetter(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1);
}
function findMostDescriptiveName(segments: readonly string[]): string | undefined {
const meaningfulSegments = segments.filter(isMeaningfulPathSegment);
if (meaningfulSegments.length === 0) {
return undefined;
}
const longestGoodSegment = meaningfulSegments.reduce((a, b) => (a.length > b.length ? a : b));
return longestGoodSegment;
}
function isMeaningfulPathSegment(segment: string): boolean {
return segment.length > 2 // This is often non-human categories like T5 etc.
&& !isNumeric(segment) // E.g. article numbers, issue numbers
&& !/^index(?:\.\S{0,10}$|$)/.test(segment) // E.g. index.html
&& !/^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))$/.test(segment) // Locale string e.g. fr-FR
&& !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(segment) // GUID
&& !/^[0-9a-f]{40}$/.test(segment); // Git SHA (e.g. GitHub links)
}
const AnchorAttributesForExternalLinks: Record<string, string> = {
target: '_blank',
rel: 'noopener noreferrer',
};
function configureLinksToOpenInNewTab(markdownParser: MarkdownIt): void {
// https://github.com/markdown-it/markdown-it/blob/12.2.0/docs/architecture.md#renderer
const defaultLinkRenderer = getDefaultRenderer(markdownParser, 'link_open');
markdownParser.renderer.rules.link_open = (tokens, index, options, env, self) => {
const currentToken = tokens[index];
Object.entries(AnchorAttributesForExternalLinks).forEach(([attribute, value]) => {
const existingValue = getTokenAttribute(currentToken, attribute);
if (!existingValue) {
addAttributeToToken(currentToken, attribute, value);
} else if (existingValue !== value) {
updateTokenAttribute(currentToken, attribute, value);
}
});
return defaultLinkRenderer(tokens, index, options, env, self);
};
}
function getDefaultRenderer(md: MarkdownIt, ruleName: string): Renderer.RenderRule {
const ruleRenderer = md.renderer.rules[ruleName];
return ruleRenderer || renderTokenAsDefault;
function renderTokenAsDefault(tokens, idx, options, _env, self) {
return self.renderToken(tokens, idx, options);
}
}
function getTokenAttribute(token: Token, attributeName: string): string | undefined {
const attributeIndex = token.attrIndex(attributeName);
if (attributeIndex < 0) {
return undefined;
}
const value = token.attrs[attributeIndex][1];
return value;
}
function addAttributeToToken(token: Token, attributeName: string, value: string): void {
token.attrPush([attributeName, value]);
}
function updateTokenAttribute(token: Token, attributeName: string, newValue: string): void {
const attributeIndex = token.attrIndex(attributeName);
if (attributeIndex < 0) {
throw new Error(`Attribute "${attributeName}" not found in token.`);
}
token.attrs[attributeIndex][1] = newValue;
}

View File

@@ -8,7 +8,7 @@
<script lang="ts">
import { defineComponent, computed } from 'vue';
import { createMarkdownRenderer } from './MarkdownRenderer';
import { CompositeMarkdownRenderer } from './CompositeMarkdownRenderer';
export default defineComponent({
props: {
@@ -26,9 +26,8 @@ export default defineComponent({
},
});
const renderer = createMarkdownRenderer();
function convertMarkdownToHtml(markdownText: string): string {
const renderer = new CompositeMarkdownRenderer();
return renderer.render(markdownText);
}
</script>
@@ -38,12 +37,11 @@ function convertMarkdownToHtml(markdownText: string): string {
@import './markdown-styles.scss';
$text-color: $color-on-primary;
$text-size: 0.75em; // Lower looks bad on Firefox
.markdown-text {
color: $text-color;
font-size: $text-size;
font-size: $font-size-absolute-normal;
font-family: $font-main;
@include markdown-text-styles($text-size: $text-size);
@include markdown-text-styles;
}
</style>

View File

@@ -0,0 +1,36 @@
import type { MarkdownRenderer } from '../MarkdownRenderer';
export class InlineReferenceLabelsToSuperscriptConverter implements MarkdownRenderer {
public render(markdownContent: string): string {
return convertInlineReferenceLabelsToSuperscript(markdownContent);
}
}
function convertInlineReferenceLabelsToSuperscript(content: string): string {
if (!content) {
return content;
}
return content.replaceAll(TextInsideBracketsPattern, (_fullMatch, label, offset) => {
if (!isInlineReferenceLabel(label, content, offset)) {
return `[${label}]`;
}
return `<sup>[${label}]</sup>`;
});
}
function isInlineReferenceLabel(
referenceLabel: string,
markdownText: string,
openingBracketPosition: number,
): boolean {
const referenceLabelDefinitionIndex = markdownText.indexOf(`\n[${referenceLabel}]: `);
if (openingBracketPosition - 1 /* -1 for newline */ === referenceLabelDefinitionIndex) {
return false; // It is a reference definition, not a label.
}
if (referenceLabelDefinitionIndex === -1) {
return false; // The reference definition is missing.
}
return true;
}
const TextInsideBracketsPattern = /\[(.*?)\]/gm;

View File

@@ -0,0 +1,40 @@
import MarkdownIt from 'markdown-it';
import type { MarkdownRenderer } from '../MarkdownRenderer';
import type { RenderRule } from 'markdown-it/lib/renderer';
export class MarkdownItHtmlRenderer implements MarkdownRenderer {
public render(markdownContent: string): string {
const markdownParser = new MarkdownIt({
html: true, // Enable HTML tags in source to allow other custom rendering logic.
linkify: false, // Disables auto-linking; handled manually for custom formatting.
breaks: false, // Disables conversion of single newlines (`\n`) to HTML breaks (`<br>`).
});
configureLinksToOpenInNewTab(markdownParser);
return markdownParser.render(markdownContent);
}
}
function configureLinksToOpenInNewTab(markdownParser: MarkdownIt): void {
// https://github.com/markdown-it/markdown-it/blob/14.0.0/docs/architecture.md#renderer
const defaultLinkRenderer = getDefaultRenderer(markdownParser, 'link_open');
markdownParser.renderer.rules.link_open = (tokens, index, options, env, self) => {
const currentToken = tokens[index];
Object.entries(AnchorAttributesForExternalLinks).forEach(([attribute, value]) => {
currentToken.attrSet(attribute, value);
});
return defaultLinkRenderer(tokens, index, options, env, self);
};
}
function getDefaultRenderer(md: MarkdownIt, ruleName: string): RenderRule {
const ruleRenderer = md.renderer.rules[ruleName];
const renderTokenAsDefault: RenderRule = (tokens, idx, options, _env, self) => {
return self.renderToken(tokens, idx, options);
};
return ruleRenderer || renderTokenAsDefault;
}
const AnchorAttributesForExternalLinks: Record<string, string> = {
target: '_blank',
rel: 'noopener noreferrer',
} as const;

View File

@@ -0,0 +1,127 @@
import type { MarkdownRenderer } from '../MarkdownRenderer';
export class PlainTextUrlsToHyperlinksConverter implements MarkdownRenderer {
public render(markdownContent: string): string {
return autoLinkPlainUrls(markdownContent);
}
}
const PlainTextUrlInMarkdownRegex = /(?<!\]\(|\[\d+\]:\s+|https?\S+|`)((?:https?):\/\/[^\s\])]*)(?:[\])](?!\()|$|\s)/gm;
function autoLinkPlainUrls(content: string): string {
if (!content) {
return content;
}
return content.replaceAll(PlainTextUrlInMarkdownRegex, (fullMatch, url) => {
return fullMatch.replace(url, formatReadableLink(url));
});
}
function formatReadableLink(url: string): string {
const urlParts = new URL(url);
let displayText = formatHostName(urlParts.hostname);
const pageLabel = extractPageLabel(urlParts);
if (pageLabel) {
displayText += ` - ${truncateTextFromEnd(capitalizeEachWord(pageLabel), 50)}`;
}
return buildMarkdownLink(displayText, url);
}
function formatHostName(hostname: string): string {
const withoutWww = hostname.replace(/^(www\.)/, '');
const truncatedHostName = truncateTextFromStart(withoutWww, 30);
return truncatedHostName;
}
function extractPageLabel(urlParts: URL): string | undefined {
const readablePath = makePathReadable(urlParts.pathname);
if (readablePath) {
return readablePath;
}
return formatQueryParameters(urlParts.searchParams);
}
function buildMarkdownLink(label: string, url: string): string {
return `[${label}](${url})`;
}
function formatQueryParameters(queryParameters: URLSearchParams): string | undefined {
const queryValues = [...queryParameters.values()];
if (queryValues.length === 0) {
return undefined;
}
return findMostDescriptiveName(queryValues);
}
function truncateTextFromStart(text: string, maxLength: number): string {
return text.length > maxLength ? `${text.substring(text.length - maxLength)}` : text;
}
function truncateTextFromEnd(text: string, maxLength: number): string {
return text.length > maxLength ? `${text.substring(0, maxLength)}` : text;
}
function isNumeric(value: string): boolean {
return /^\d+$/.test(value);
}
function makePathReadable(path: string): string | undefined {
const decodedPath = decodeURI(path); // Decode URI components, e.g., '%20' to space
const pathParts = decodedPath.split('/');
const decodedPathParts = pathParts // Split then decode to correctly handle '%2F' as '/'
.map((pathPart) => decodeURIComponent(pathPart));
const descriptivePart = findMostDescriptiveName(decodedPathParts);
if (!descriptivePart) {
return undefined;
}
const withoutExtension = removeFileExtension(descriptivePart);
const tokenizedText = tokenizeTextForReadability(withoutExtension);
return tokenizedText;
}
function tokenizeTextForReadability(text: string): string {
return text
.replaceAll(/[-_+]/g, ' ') // Replace hyphens, underscores, and plus signs with spaces
.replaceAll(/\s+/g, ' '); // Collapse multiple consecutive spaces into a single space
}
function removeFileExtension(value: string): string {
const parts = value.split('.');
if (parts.length === 1) {
return value;
}
const extension = parts[parts.length - 1];
if (extension.length > 9) {
return value; // Heuristically web file extension is no longer than 9 chars (e.g. "html")
}
return parts.slice(0, -1).join('.');
}
function capitalizeEachWord(text: string): string {
return text
.split(' ')
.map((word) => capitalizeFirstLetter(word))
.join(' ');
}
function capitalizeFirstLetter(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1);
}
function findMostDescriptiveName(segments: readonly string[]): string | undefined {
const meaningfulSegments = segments.filter(isMeaningfulPathSegment);
if (meaningfulSegments.length === 0) {
return undefined;
}
const longestGoodSegment = meaningfulSegments.reduce((a, b) => (a.length > b.length ? a : b));
return longestGoodSegment;
}
function isMeaningfulPathSegment(segment: string): boolean {
return segment.length > 2 // This is often non-human categories like T5 etc.
&& !isNumeric(segment) // E.g. article numbers, issue numbers
&& !/^index(?:\.\S{0,10}$|$)/.test(segment) // E.g. index.html
&& !/^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))$/.test(segment) // Locale string e.g. fr-FR
&& !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(segment) // GUID
&& !/^[0-9a-f]{40}$/.test(segment); // Git SHA (e.g. GitHub links)
}

View File

@@ -55,8 +55,8 @@
@include left-padding('ul, ol', $large-horizontal-spacing);
}
@mixin markdown-text-styles($text-size) {
$base-spacing: $text-size;
@mixin markdown-text-styles {
$base-spacing: 1em;
a {
&[href] {
@@ -73,11 +73,19 @@
content: '';
display: inline-block;
width: $text-size;
height: $text-size;
/*
Use absolute sizing instead of relative. Relative sizing looks bad and inconsistent if there are external elements
inside small text (such as inside `<sup>`) and bigger elements like in bigger text. Making them always have same size
make the text read and flow better.
*/
width: $font-size-absolute-x-small;
height: $font-size-absolute-x-small;
vertical-align: text-top;
background-color: $text-color;
margin-left: math.div($text-size, 4);
margin-left: math.div(1em, 4);
}
/*
Match color of global hover behavior. We need to do it manually because global hover sets
@@ -113,4 +121,11 @@
$code-block-padding: $base-spacing,
$color-background: $color-primary-darker,
);
sup {
@include reset-sup;
vertical-align: super;
font-size: $font-size-relative-smallest;
}
}

View File

@@ -24,6 +24,6 @@ export default defineComponent({
.node-title {
font-family: $font-main;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
}
</style>

View File

@@ -75,7 +75,7 @@ export default defineComponent({
@use 'sass:math';
@use "@/presentation/assets/styles/main" as *;
$font-size : $font-size-small;
$font-size : $font-size-absolute-small;
$color-toggle-unchecked : $color-primary-darker;
$color-toggle-checked : $color-on-secondary;

View File

@@ -53,7 +53,7 @@ export default defineComponent({
@use "@/presentation/assets/styles/main" as *;
@use "./../tree-colors" as *;
$side-size-in-px: $font-size-larger;
$side-size-in-px: $font-size-absolute-x-large;
.checkbox {
position: relative;

View File

@@ -74,7 +74,7 @@ export default defineComponent({
.dialog__close-button {
color: $color-primary-dark;
width: auto;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
margin-right: 0.25em;
align-self: flex-start;
}

View File

@@ -225,7 +225,7 @@ $color-tooltip-background: $color-primary-darkest;
color: $color-on-primary;
border-radius: 16px;
padding: 5px 10px 4px;
font-size: $font-size-normal;
font-size: $font-size-absolute-normal;
/*
This margin creates a visual buffer between the tooltip and the edges of the document.

View File

@@ -78,7 +78,7 @@ export default defineComponent({
&__url {
&:not(:first-child)::before {
content: "|";
font-size: $font-size-smaller;
font-size: $font-size-absolute-x-small;
padding: 0 5px;
}
}

View File

@@ -65,7 +65,7 @@ function hasDesktopVersion(os: OperatingSystem): boolean {
@use "@/presentation/assets/styles/main" as *;
.url {
.inactive {
font-size: $font-size-smaller;
font-size: $font-size-absolute-x-small;
}
}
</style>

View File

@@ -46,11 +46,11 @@ export default defineComponent({
margin: 0;
text-transform: uppercase;
font-family: $font-main;
font-size: $font-size-largest;
font-size: $font-size-absolute-xx-large;
}
.subtitle {
margin: 0;
font-size: $font-size-larger;
font-size: $font-size-absolute-x-large;
color: $color-primary;
font-family: $font-artistic;
font-weight: 500;

View File

@@ -113,7 +113,7 @@ export default defineComponent({
outline: none;
color: $color-primary;
font-family: $font-normal;
font-size: $font-size-normal;
font-size: $font-size-absolute-normal;
&:focus {
color: $color-primary-darker;
}
@@ -127,7 +127,7 @@ export default defineComponent({
text-align: center;
color: $color-on-primary;
border-radius: 0 5px 5px 0;
font-size: $font-size-large;
font-size: $font-size-absolute-large;
padding:5px;
}
</style>